LCOV - code coverage report
Current view: top level - src/verdict - V_HexMetric.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 1371 1520 90.2 %
Date: 2020-12-16 07:07:30 Functions: 30 32 93.8 %
Branches: 1414 2878 49.1 %

           Branch data     Line data    Source code
       1                 :            : /*=========================================================================
       2                 :            : 
       3                 :            :   Module:    $RCSfile: V_HexMetric.cpp,v $
       4                 :            : 
       5                 :            :   Copyright (c) 2006 Sandia Corporation.
       6                 :            :   All rights reserved.
       7                 :            :   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
       8                 :            : 
       9                 :            :      This software is distributed WITHOUT ANY WARRANTY; without even
      10                 :            :      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
      11                 :            :      PURPOSE.  See the above copyright notice for more information.
      12                 :            : 
      13                 :            : =========================================================================*/
      14                 :            : 
      15                 :            : /*
      16                 :            :  *
      17                 :            :  * HexMetric.cpp contains quality calculations for hexes
      18                 :            :  *
      19                 :            :  * This file is part of VERDICT
      20                 :            :  *
      21                 :            :  */
      22                 :            : 
      23                 :            : #define VERDICT_EXPORTS
      24                 :            : 
      25                 :            : #include "moab/verdict.h"
      26                 :            : #include "VerdictVector.hpp"
      27                 :            : #include "V_GaussIntegration.hpp"
      28                 :            : #include "verdict_defines.hpp"
      29                 :            : #include <memory.h>
      30                 :            : 
      31                 :            : #if defined( __BORLANDC__ )
      32                 :            : #pragma warn - 8004 /* "assigned a value that is never used" */
      33                 :            : #endif
      34                 :            : 
      35                 :            : //! the average volume of a hex
      36                 :            : double verdict_hex_size = 0;
      37                 :            : 
      38                 :            : //! weights based on the average size of a hex
      39                 :         35 : int v_hex_get_weight( VerdictVector& v1, VerdictVector& v2, VerdictVector& v3 )
      40                 :            : {
      41                 :            : 
      42         [ -  + ]:         35 :     if( verdict_hex_size == 0 ) return 0;
      43                 :            : 
      44                 :         35 :     v1.set( 1, 0, 0 );
      45                 :         35 :     v2.set( 0, 1, 0 );
      46                 :         35 :     v3.set( 0, 0, 1 );
      47                 :            : 
      48         [ +  - ]:         35 :     double scale = pow( verdict_hex_size / ( v1 % ( v2 * v3 ) ), 0.33333333333 );
      49                 :         35 :     v1 *= scale;
      50                 :         35 :     v2 *= scale;
      51                 :         35 :     v3 *= scale;
      52                 :            : 
      53                 :         35 :     return 1;
      54                 :            : }
      55                 :            : 
      56                 :            : //! returns the average volume of a hex
      57                 :          1 : C_FUNC_DEF void v_set_hex_size( double size )
      58                 :            : {
      59                 :          1 :     verdict_hex_size = size;
      60                 :          1 : }
      61                 :            : 
      62                 :            : #define make_hex_nodes( coord, pos )                                         \
      63                 :            :     for( int mhcii = 0; mhcii < 8; mhcii++ )                                 \
      64                 :            :     {                                                                        \
      65                 :            :         pos[mhcii].set( coord[mhcii][0], coord[mhcii][1], coord[mhcii][2] ); \
      66                 :            :     }
      67                 :            : 
      68                 :            : #define make_edge_length_squares( edges, lengths )          \
      69                 :            :     {                                                       \
      70                 :            :         for( int melii = 0; melii < 12; melii++ )           \
      71                 :            :             lengths[melii] = edges[melii].length_squared(); \
      72                 :            :     }
      73                 :            : 
      74                 :            : //! make VerdictVectors from coordinates
      75                 :         24 : void make_hex_edges( double coordinates[][3], VerdictVector edges[12] )
      76                 :            : {
      77                 :         48 :     edges[0].set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
      78                 :         24 :                   coordinates[1][2] - coordinates[0][2] );
      79                 :         48 :     edges[1].set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
      80                 :         24 :                   coordinates[2][2] - coordinates[1][2] );
      81                 :         48 :     edges[2].set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
      82                 :         24 :                   coordinates[3][2] - coordinates[2][2] );
      83                 :         48 :     edges[3].set( coordinates[0][0] - coordinates[3][0], coordinates[0][1] - coordinates[3][1],
      84                 :         24 :                   coordinates[0][2] - coordinates[3][2] );
      85                 :         48 :     edges[4].set( coordinates[5][0] - coordinates[4][0], coordinates[5][1] - coordinates[4][1],
      86                 :         24 :                   coordinates[5][2] - coordinates[4][2] );
      87                 :         48 :     edges[5].set( coordinates[6][0] - coordinates[5][0], coordinates[6][1] - coordinates[5][1],
      88                 :         24 :                   coordinates[6][2] - coordinates[5][2] );
      89                 :         48 :     edges[6].set( coordinates[7][0] - coordinates[6][0], coordinates[7][1] - coordinates[6][1],
      90                 :         24 :                   coordinates[7][2] - coordinates[6][2] );
      91                 :         48 :     edges[7].set( coordinates[4][0] - coordinates[7][0], coordinates[4][1] - coordinates[7][1],
      92                 :         24 :                   coordinates[4][2] - coordinates[7][2] );
      93                 :         48 :     edges[8].set( coordinates[4][0] - coordinates[0][0], coordinates[4][1] - coordinates[0][1],
      94                 :         24 :                   coordinates[4][2] - coordinates[0][2] );
      95                 :         48 :     edges[9].set( coordinates[5][0] - coordinates[1][0], coordinates[5][1] - coordinates[1][1],
      96                 :         24 :                   coordinates[5][2] - coordinates[1][2] );
      97                 :         48 :     edges[10].set( coordinates[6][0] - coordinates[2][0], coordinates[6][1] - coordinates[2][1],
      98                 :         24 :                    coordinates[6][2] - coordinates[2][2] );
      99                 :         48 :     edges[11].set( coordinates[7][0] - coordinates[3][0], coordinates[7][1] - coordinates[3][1],
     100                 :         24 :                    coordinates[7][2] - coordinates[3][2] );
     101                 :         24 : }
     102                 :            : 
     103                 :            : /*!
     104                 :            :   localizes hex coordinates
     105                 :            : */
     106                 :          0 : void localize_hex_coordinates( double coordinates[][3], VerdictVector position[8] )
     107                 :            : {
     108                 :            : 
     109                 :            :     int ii;
     110         [ #  # ]:          0 :     for( ii = 0; ii < 8; ii++ )
     111                 :            :     {
     112         [ #  # ]:          0 :         position[ii].set( coordinates[ii][0], coordinates[ii][1], coordinates[ii][2] );
     113                 :            :     }
     114                 :            : 
     115                 :            :     // ... Make centroid of element the center of coordinate system
     116         [ #  # ]:          0 :     VerdictVector point_1256 = position[1];
     117         [ #  # ]:          0 :     point_1256 += position[2];
     118         [ #  # ]:          0 :     point_1256 += position[5];
     119         [ #  # ]:          0 :     point_1256 += position[6];
     120                 :            : 
     121         [ #  # ]:          0 :     VerdictVector point_0374 = position[0];
     122         [ #  # ]:          0 :     point_0374 += position[3];
     123         [ #  # ]:          0 :     point_0374 += position[7];
     124         [ #  # ]:          0 :     point_0374 += position[4];
     125                 :            : 
     126         [ #  # ]:          0 :     VerdictVector centroid = point_1256;
     127         [ #  # ]:          0 :     centroid += point_0374;
     128         [ #  # ]:          0 :     centroid /= 8.0;
     129                 :            : 
     130                 :            :     int i;
     131         [ #  # ]:          0 :     for( i = 0; i < 8; i++ )
     132         [ #  # ]:          0 :         position[i] -= centroid;
     133                 :            : 
     134                 :            :     // ... Rotate element such that center of side 1-2 and 0-3 define X axis
     135 [ #  # ][ #  # ]:          0 :     double DX = point_1256.x() - point_0374.x();
     136 [ #  # ][ #  # ]:          0 :     double DY = point_1256.y() - point_0374.y();
     137 [ #  # ][ #  # ]:          0 :     double DZ = point_1256.z() - point_0374.z();
     138                 :            : 
     139                 :          0 :     double AMAGX = sqrt( DX * DX + DZ * DZ );
     140                 :          0 :     double AMAGY = sqrt( DX * DX + DY * DY + DZ * DZ );
     141         [ #  # ]:          0 :     double FMAGX = AMAGX == 0.0 ? 1.0 : 0.0;
     142         [ #  # ]:          0 :     double FMAGY = AMAGY == 0.0 ? 1.0 : 0.0;
     143                 :            : 
     144                 :          0 :     double CZ = DX / ( AMAGX + FMAGX ) + FMAGX;
     145                 :          0 :     double SZ = DZ / ( AMAGX + FMAGX );
     146                 :          0 :     double CY = AMAGX / ( AMAGY + FMAGY ) + FMAGY;
     147                 :          0 :     double SY = DY / ( AMAGY + FMAGY );
     148                 :            : 
     149                 :            :     double temp;
     150                 :            : 
     151         [ #  # ]:          0 :     for( i = 0; i < 8; i++ )
     152                 :            :     {
     153 [ #  # ][ #  # ]:          0 :         temp = CY * CZ * position[i].x() + CY * SZ * position[i].z() + SY * position[i].y();
                 [ #  # ]
     154 [ #  # ][ #  # ]:          0 :         position[i].y( -SY * CZ * position[i].x() - SY * SZ * position[i].z() + CY * position[i].y() );
         [ #  # ][ #  # ]
     155 [ #  # ][ #  # ]:          0 :         position[i].z( -SZ * position[i].x() + CZ * position[i].z() );
                 [ #  # ]
     156         [ #  # ]:          0 :         position[i].x( temp );
     157                 :            :     }
     158                 :            : 
     159                 :            :     // ... Now, rotate about Y
     160         [ #  # ]:          0 :     VerdictVector delta = -position[0];
     161         [ #  # ]:          0 :     delta -= position[1];
     162         [ #  # ]:          0 :     delta += position[2];
     163         [ #  # ]:          0 :     delta += position[3];
     164         [ #  # ]:          0 :     delta -= position[4];
     165         [ #  # ]:          0 :     delta -= position[5];
     166         [ #  # ]:          0 :     delta += position[6];
     167         [ #  # ]:          0 :     delta += position[7];
     168                 :            : 
     169         [ #  # ]:          0 :     DY = delta.y();
     170         [ #  # ]:          0 :     DZ = delta.z();
     171                 :            : 
     172                 :          0 :     AMAGY = sqrt( DY * DY + DZ * DZ );
     173         [ #  # ]:          0 :     FMAGY = AMAGY == 0.0 ? 1.0 : 0.0;
     174                 :            : 
     175                 :          0 :     double CX = DY / ( AMAGY + FMAGY ) + FMAGY;
     176                 :          0 :     double SX = DZ / ( AMAGY + FMAGY );
     177                 :            : 
     178         [ #  # ]:          0 :     for( i = 0; i < 8; i++ )
     179                 :            :     {
     180 [ #  # ][ #  # ]:          0 :         temp = CX * position[i].y() + SX * position[i].z();
     181 [ #  # ][ #  # ]:          0 :         position[i].z( -SX * position[i].y() + CX * position[i].z() );
                 [ #  # ]
     182         [ #  # ]:          0 :         position[i].y( temp );
     183                 :            :     }
     184                 :          0 : }
     185                 :            : 
     186                 :          0 : double safe_ratio3( const double numerator, const double denominator, const double max_ratio )
     187                 :            : {
     188                 :            :     // this filter is essential for good running time in practice
     189                 :            :     double return_value;
     190                 :            : 
     191                 :          0 :     const double filter_n = max_ratio * 1.0e-16;
     192                 :          0 :     const double filter_d = 1.0e-16;
     193 [ #  # ][ #  # ]:          0 :     if( fabs( numerator ) <= filter_n && fabs( denominator ) >= filter_d ) { return_value = numerator / denominator; }
     194                 :            :     else
     195                 :            :     {
     196                 :          0 :         return_value = fabs( numerator ) / max_ratio >= fabs( denominator )
     197 [ #  # ][ #  # ]:          0 :                            ? ( ( numerator >= 0.0 && denominator >= 0.0 ) || ( numerator < 0.0 && denominator < 0.0 )
                 [ #  # ]
     198                 :            :                                    ? max_ratio
     199                 :            :                                    : -max_ratio )
     200 [ #  # ][ #  # ]:          0 :                            : numerator / denominator;
     201                 :            :     }
     202                 :            : 
     203                 :          0 :     return return_value;
     204                 :            : }
     205                 :            : 
     206                 :        133 : double safe_ratio( const double numerator, const double denominator )
     207                 :            : {
     208                 :            : 
     209                 :            :     double return_value;
     210                 :        133 :     const double filter_n = VERDICT_DBL_MAX;
     211                 :        133 :     const double filter_d = VERDICT_DBL_MIN;
     212 [ +  - ][ +  - ]:        133 :     if( fabs( numerator ) <= filter_n && fabs( denominator ) >= filter_d ) { return_value = numerator / denominator; }
     213                 :            :     else
     214                 :            :     {
     215                 :          0 :         return_value = VERDICT_DBL_MAX;
     216                 :            :     }
     217                 :            : 
     218                 :        133 :     return return_value;
     219                 :            : }
     220                 :            : 
     221                 :        353 : double condition_comp( const VerdictVector& xxi, const VerdictVector& xet, const VerdictVector& xze )
     222                 :            : {
     223         [ +  - ]:        353 :     double det = xxi % ( xet * xze );
     224                 :            : 
     225         [ -  + ]:        353 :     if( det <= VERDICT_DBL_MIN ) { return VERDICT_DBL_MAX; }
     226                 :            : 
     227                 :        353 :     double term1 = xxi % xxi + xet % xet + xze % xze;
     228                 :            :     double term2 =
     229 [ +  - ][ +  - ]:        353 :         ( ( xxi * xet ) % ( xxi * xet ) ) + ( ( xet * xze ) % ( xet * xze ) ) + ( ( xze * xxi ) % ( xze * xxi ) );
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     230                 :            : 
     231                 :        353 :     return sqrt( term1 * term2 ) / det;
     232                 :            : }
     233                 :            : 
     234                 :        144 : double oddy_comp( const VerdictVector& xxi, const VerdictVector& xet, const VerdictVector& xze )
     235                 :            : {
     236                 :            :     static const double third = 1.0 / 3.0;
     237                 :            : 
     238                 :            :     double g11, g12, g13, g22, g23, g33, rt_g;
     239                 :            : 
     240                 :        144 :     g11  = xxi % xxi;
     241                 :        144 :     g12  = xxi % xet;
     242                 :        144 :     g13  = xxi % xze;
     243                 :        144 :     g22  = xet % xet;
     244                 :        144 :     g23  = xet % xze;
     245                 :        144 :     g33  = xze % xze;
     246         [ +  - ]:        144 :     rt_g = xxi % ( xet * xze );
     247                 :            : 
     248                 :            :     double oddy_metric;
     249         [ +  - ]:        144 :     if( rt_g > VERDICT_DBL_MIN )
     250                 :            :     {
     251                 :        144 :         double norm_G_squared = g11 * g11 + 2.0 * g12 * g12 + 2.0 * g13 * g13 + g22 * g22 + 2.0 * g23 * g23 + g33 * g33;
     252                 :            : 
     253                 :        144 :         double norm_J_squared = g11 + g22 + g33;
     254                 :            : 
     255                 :        144 :         oddy_metric = ( norm_G_squared - third * norm_J_squared * norm_J_squared ) / pow( rt_g, 4. * third );
     256                 :            :     }
     257                 :            : 
     258                 :            :     else
     259                 :          0 :         oddy_metric = VERDICT_DBL_MAX;
     260                 :            : 
     261                 :        144 :     return oddy_metric;
     262                 :            : }
     263                 :            : 
     264                 :            : //! calcualates edge lengths of a hex
     265                 :          9 : double hex_edge_length( int max_min, double coordinates[][3] )
     266                 :            : {
     267                 :            :     double temp[3], edge[12];
     268                 :            :     int i;
     269                 :            : 
     270                 :            :     // lengths^2 of edges
     271         [ +  + ]:         36 :     for( i = 0; i < 3; i++ )
     272                 :            :     {
     273                 :         27 :         temp[i] = coordinates[1][i] - coordinates[0][i];
     274                 :         27 :         temp[i] = temp[i] * temp[i];
     275                 :            :     }
     276                 :          9 :     edge[0] = sqrt( temp[0] + temp[1] + temp[2] );
     277                 :            : 
     278         [ +  + ]:         36 :     for( i = 0; i < 3; i++ )
     279                 :            :     {
     280                 :         27 :         temp[i] = coordinates[2][i] - coordinates[1][i];
     281                 :         27 :         temp[i] = temp[i] * temp[i];
     282                 :            :     }
     283                 :          9 :     edge[1] = sqrt( temp[0] + temp[1] + temp[2] );
     284                 :            : 
     285         [ +  + ]:         36 :     for( i = 0; i < 3; i++ )
     286                 :            :     {
     287                 :         27 :         temp[i] = coordinates[3][i] - coordinates[2][i];
     288                 :         27 :         temp[i] = temp[i] * temp[i];
     289                 :            :     }
     290                 :          9 :     edge[2] = sqrt( temp[0] + temp[1] + temp[2] );
     291                 :            : 
     292         [ +  + ]:         36 :     for( i = 0; i < 3; i++ )
     293                 :            :     {
     294                 :         27 :         temp[i] = coordinates[0][i] - coordinates[3][i];
     295                 :         27 :         temp[i] = temp[i] * temp[i];
     296                 :            :     }
     297                 :          9 :     edge[3] = sqrt( temp[0] + temp[1] + temp[2] );
     298                 :            : 
     299         [ +  + ]:         36 :     for( i = 0; i < 3; i++ )
     300                 :            :     {
     301                 :         27 :         temp[i] = coordinates[5][i] - coordinates[4][i];
     302                 :         27 :         temp[i] = temp[i] * temp[i];
     303                 :            :     }
     304                 :          9 :     edge[4] = sqrt( temp[0] + temp[1] + temp[2] );
     305                 :            : 
     306         [ +  + ]:         36 :     for( i = 0; i < 3; i++ )
     307                 :            :     {
     308                 :         27 :         temp[i] = coordinates[6][i] - coordinates[5][i];
     309                 :         27 :         temp[i] = temp[i] * temp[i];
     310                 :            :     }
     311                 :          9 :     edge[5] = sqrt( temp[0] + temp[1] + temp[2] );
     312                 :            : 
     313         [ +  + ]:         36 :     for( i = 0; i < 3; i++ )
     314                 :            :     {
     315                 :         27 :         temp[i] = coordinates[7][i] - coordinates[6][i];
     316                 :         27 :         temp[i] = temp[i] * temp[i];
     317                 :            :     }
     318                 :          9 :     edge[6] = sqrt( temp[0] + temp[1] + temp[2] );
     319                 :            : 
     320         [ +  + ]:         36 :     for( i = 0; i < 3; i++ )
     321                 :            :     {
     322                 :         27 :         temp[i] = coordinates[4][i] - coordinates[7][i];
     323                 :         27 :         temp[i] = temp[i] * temp[i];
     324                 :            :     }
     325                 :          9 :     edge[7] = sqrt( temp[0] + temp[1] + temp[2] );
     326                 :            : 
     327         [ +  + ]:         36 :     for( i = 0; i < 3; i++ )
     328                 :            :     {
     329                 :         27 :         temp[i] = coordinates[4][i] - coordinates[0][i];
     330                 :         27 :         temp[i] = temp[i] * temp[i];
     331                 :            :     }
     332                 :          9 :     edge[8] = sqrt( temp[0] + temp[1] + temp[2] );
     333                 :            : 
     334         [ +  + ]:         36 :     for( i = 0; i < 3; i++ )
     335                 :            :     {
     336                 :         27 :         temp[i] = coordinates[5][i] - coordinates[1][i];
     337                 :         27 :         temp[i] = temp[i] * temp[i];
     338                 :            :     }
     339                 :          9 :     edge[9] = sqrt( temp[0] + temp[1] + temp[2] );
     340                 :            : 
     341         [ +  + ]:         36 :     for( i = 0; i < 3; i++ )
     342                 :            :     {
     343                 :         27 :         temp[i] = coordinates[6][i] - coordinates[2][i];
     344                 :         27 :         temp[i] = temp[i] * temp[i];
     345                 :            :     }
     346                 :          9 :     edge[10] = sqrt( temp[0] + temp[1] + temp[2] );
     347                 :            : 
     348         [ +  + ]:         36 :     for( i = 0; i < 3; i++ )
     349                 :            :     {
     350                 :         27 :         temp[i] = coordinates[7][i] - coordinates[3][i];
     351                 :         27 :         temp[i] = temp[i] * temp[i];
     352                 :            :     }
     353                 :          9 :     edge[11] = sqrt( temp[0] + temp[1] + temp[2] );
     354                 :            : 
     355                 :          9 :     double _edge = edge[0];
     356                 :            : 
     357         [ +  - ]:          9 :     if( max_min == 0 )
     358                 :            :     {
     359         [ +  + ]:        108 :         for( i = 1; i < 12; i++ )
     360         [ +  + ]:         99 :             _edge = VERDICT_MIN( _edge, edge[i] );
     361                 :          9 :         return (double)_edge;
     362                 :            :     }
     363                 :            :     else
     364                 :            :     {
     365         [ #  # ]:          0 :         for( i = 1; i < 12; i++ )
     366         [ #  # ]:          0 :             _edge = VERDICT_MAX( _edge, edge[i] );
     367                 :          9 :         return (double)_edge;
     368                 :            :     }
     369                 :            : }
     370                 :            : 
     371                 :         51 : double diag_length( int max_min, double coordinates[][3] )
     372                 :            : {
     373                 :            :     double temp[3], diag[4];
     374                 :            :     int i;
     375                 :            : 
     376                 :            :     // lengths^2  f diag nals
     377         [ +  + ]:        204 :     for( i = 0; i < 3; i++ )
     378                 :            :     {
     379                 :        153 :         temp[i] = coordinates[6][i] - coordinates[0][i];
     380                 :        153 :         temp[i] = temp[i] * temp[i];
     381                 :            :     }
     382                 :         51 :     diag[0] = sqrt( temp[0] + temp[1] + temp[2] );
     383                 :            : 
     384         [ +  + ]:        204 :     for( i = 0; i < 3; i++ )
     385                 :            :     {
     386                 :        153 :         temp[i] = coordinates[4][i] - coordinates[2][i];
     387                 :        153 :         temp[i] = temp[i] * temp[i];
     388                 :            :     }
     389                 :         51 :     diag[1] = sqrt( temp[0] + temp[1] + temp[2] );
     390                 :            : 
     391         [ +  + ]:        204 :     for( i = 0; i < 3; i++ )
     392                 :            :     {
     393                 :        153 :         temp[i] = coordinates[7][i] - coordinates[1][i];
     394                 :        153 :         temp[i] = temp[i] * temp[i];
     395                 :            :     }
     396                 :         51 :     diag[2] = sqrt( temp[0] + temp[1] + temp[2] );
     397                 :            : 
     398         [ +  + ]:        204 :     for( i = 0; i < 3; i++ )
     399                 :            :     {
     400                 :        153 :         temp[i] = coordinates[5][i] - coordinates[3][i];
     401                 :        153 :         temp[i] = temp[i] * temp[i];
     402                 :            :     }
     403                 :         51 :     diag[3] = sqrt( temp[0] + temp[1] + temp[2] );
     404                 :            : 
     405                 :         51 :     double diagonal = diag[0];
     406         [ +  + ]:         51 :     if( max_min == 0 )  // Return min diagonal
     407                 :            :     {
     408         [ +  + ]:         68 :         for( i = 1; i < 4; i++ )
     409         [ +  + ]:         51 :             diagonal = VERDICT_MIN( diagonal, diag[i] );
     410                 :         17 :         return (double)diagonal;
     411                 :            :     }
     412                 :            :     else  // Return max diagonal
     413                 :            :     {
     414         [ +  + ]:        136 :         for( i = 1; i < 4; i++ )
     415         [ +  + ]:        102 :             diagonal = VERDICT_MAX( diagonal, diag[i] );
     416                 :         51 :         return (double)diagonal;
     417                 :            :     }
     418                 :            : }
     419                 :            : 
     420                 :            : //! calculates efg values
     421                 :        333 : VerdictVector calc_hex_efg( int efg_index, VerdictVector coordinates[8] )
     422                 :            : {
     423                 :            : 
     424                 :        333 :     VerdictVector efg;
     425                 :            : 
     426   [ +  +  +  +  :        333 :     switch( efg_index )
             +  +  -  - ]
     427                 :            :     {
     428                 :            : 
     429                 :            :         case 1:
     430                 :         94 :             efg = coordinates[1];
     431                 :         94 :             efg += coordinates[2];
     432                 :         94 :             efg += coordinates[5];
     433                 :         94 :             efg += coordinates[6];
     434                 :         94 :             efg -= coordinates[0];
     435                 :         94 :             efg -= coordinates[3];
     436                 :         94 :             efg -= coordinates[4];
     437                 :         94 :             efg -= coordinates[7];
     438                 :         94 :             break;
     439                 :            : 
     440                 :            :         case 2:
     441                 :         94 :             efg = coordinates[2];
     442                 :         94 :             efg += coordinates[3];
     443                 :         94 :             efg += coordinates[6];
     444                 :         94 :             efg += coordinates[7];
     445                 :         94 :             efg -= coordinates[0];
     446                 :         94 :             efg -= coordinates[1];
     447                 :         94 :             efg -= coordinates[4];
     448                 :         94 :             efg -= coordinates[5];
     449                 :         94 :             break;
     450                 :            : 
     451                 :            :         case 3:
     452                 :         94 :             efg = coordinates[4];
     453                 :         94 :             efg += coordinates[5];
     454                 :         94 :             efg += coordinates[6];
     455                 :         94 :             efg += coordinates[7];
     456                 :         94 :             efg -= coordinates[0];
     457                 :         94 :             efg -= coordinates[1];
     458                 :         94 :             efg -= coordinates[2];
     459                 :         94 :             efg -= coordinates[3];
     460                 :         94 :             break;
     461                 :            : 
     462                 :            :         case 12:
     463                 :         17 :             efg = coordinates[0];
     464                 :         17 :             efg += coordinates[2];
     465                 :         17 :             efg += coordinates[4];
     466                 :         17 :             efg += coordinates[6];
     467                 :         17 :             efg -= coordinates[1];
     468                 :         17 :             efg -= coordinates[3];
     469                 :         17 :             efg -= coordinates[5];
     470                 :         17 :             efg -= coordinates[7];
     471                 :         17 :             break;
     472                 :            : 
     473                 :            :         case 13:
     474                 :         17 :             efg = coordinates[0];
     475                 :         17 :             efg += coordinates[3];
     476                 :         17 :             efg += coordinates[5];
     477                 :         17 :             efg += coordinates[6];
     478                 :         17 :             efg -= coordinates[1];
     479                 :         17 :             efg -= coordinates[2];
     480                 :         17 :             efg -= coordinates[4];
     481                 :         17 :             efg -= coordinates[7];
     482                 :         17 :             break;
     483                 :            : 
     484                 :            :         case 23:
     485                 :         17 :             efg = coordinates[0];
     486                 :         17 :             efg += coordinates[1];
     487                 :         17 :             efg += coordinates[6];
     488                 :         17 :             efg += coordinates[7];
     489                 :         17 :             efg -= coordinates[2];
     490                 :         17 :             efg -= coordinates[3];
     491                 :         17 :             efg -= coordinates[4];
     492                 :         17 :             efg -= coordinates[5];
     493                 :         17 :             break;
     494                 :            : 
     495                 :            :         case 123:
     496                 :          0 :             efg = coordinates[0];
     497                 :          0 :             efg += coordinates[2];
     498                 :          0 :             efg += coordinates[5];
     499                 :          0 :             efg += coordinates[7];
     500                 :          0 :             efg -= coordinates[1];
     501                 :          0 :             efg -= coordinates[5];
     502                 :          0 :             efg -= coordinates[6];
     503                 :          0 :             efg -= coordinates[2];
     504                 :          0 :             break;
     505                 :            : 
     506                 :            :         default:
     507                 :          0 :             efg.set( 0, 0, 0 );
     508                 :            :     }
     509                 :            : 
     510                 :        333 :     return efg;
     511                 :            : }
     512                 :            : 
     513                 :            : /*!
     514                 :            :    the edge ratio of a hex
     515                 :            : 
     516                 :            :    NB (P. Pebay 01/23/07):
     517                 :            :      Hmax / Hmin where Hmax and Hmin are respectively the maximum and the
     518                 :            :      minimum edge lengths
     519                 :            : */
     520                 :         16 : C_FUNC_DEF double v_hex_edge_ratio( int /*num_nodes*/, double coordinates[][3] )
     521                 :            : {
     522                 :            : 
     523 [ +  - ][ +  + ]:        208 :     VerdictVector edges[12];
     524         [ +  - ]:         16 :     make_hex_edges( coordinates, edges );
     525                 :            : 
     526         [ +  - ]:         16 :     double a2 = edges[0].length_squared();
     527         [ +  - ]:         16 :     double b2 = edges[1].length_squared();
     528         [ +  - ]:         16 :     double c2 = edges[2].length_squared();
     529         [ +  - ]:         16 :     double d2 = edges[3].length_squared();
     530         [ +  - ]:         16 :     double e2 = edges[4].length_squared();
     531         [ +  - ]:         16 :     double f2 = edges[5].length_squared();
     532         [ +  - ]:         16 :     double g2 = edges[6].length_squared();
     533         [ +  - ]:         16 :     double h2 = edges[7].length_squared();
     534         [ +  - ]:         16 :     double i2 = edges[8].length_squared();
     535         [ +  - ]:         16 :     double j2 = edges[9].length_squared();
     536         [ +  - ]:         16 :     double k2 = edges[10].length_squared();
     537         [ +  - ]:         16 :     double l2 = edges[11].length_squared();
     538                 :            : 
     539                 :            :     double mab, mcd, mef, Mab, Mcd, Mef;
     540                 :            :     double mgh, mij, mkl, Mgh, Mij, Mkl;
     541                 :            : 
     542         [ -  + ]:         16 :     if( a2 < b2 )
     543                 :            :     {
     544                 :          0 :         mab = a2;
     545                 :          0 :         Mab = b2;
     546                 :            :     }
     547                 :            :     else  // b2 <= a2
     548                 :            :     {
     549                 :         16 :         mab = b2;
     550                 :         16 :         Mab = a2;
     551                 :            :     }
     552         [ -  + ]:         16 :     if( c2 < d2 )
     553                 :            :     {
     554                 :          0 :         mcd = c2;
     555                 :          0 :         Mcd = d2;
     556                 :            :     }
     557                 :            :     else  // d2 <= c2
     558                 :            :     {
     559                 :         16 :         mcd = d2;
     560                 :         16 :         Mcd = c2;
     561                 :            :     }
     562         [ -  + ]:         16 :     if( e2 < f2 )
     563                 :            :     {
     564                 :          0 :         mef = e2;
     565                 :          0 :         Mef = f2;
     566                 :            :     }
     567                 :            :     else  // f2 <= e2
     568                 :            :     {
     569                 :         16 :         mef = f2;
     570                 :         16 :         Mef = e2;
     571                 :            :     }
     572         [ -  + ]:         16 :     if( g2 < h2 )
     573                 :            :     {
     574                 :          0 :         mgh = g2;
     575                 :          0 :         Mgh = h2;
     576                 :            :     }
     577                 :            :     else  // h2 <= g2
     578                 :            :     {
     579                 :         16 :         mgh = h2;
     580                 :         16 :         Mgh = g2;
     581                 :            :     }
     582         [ -  + ]:         16 :     if( i2 < j2 )
     583                 :            :     {
     584                 :          0 :         mij = i2;
     585                 :          0 :         Mij = j2;
     586                 :            :     }
     587                 :            :     else  // j2 <= i2
     588                 :            :     {
     589                 :         16 :         mij = j2;
     590                 :         16 :         Mij = i2;
     591                 :            :     }
     592         [ -  + ]:         16 :     if( k2 < l2 )
     593                 :            :     {
     594                 :          0 :         mkl = k2;
     595                 :          0 :         Mkl = l2;
     596                 :            :     }
     597                 :            :     else  // l2 <= k2
     598                 :            :     {
     599                 :         16 :         mkl = l2;
     600                 :         16 :         Mkl = k2;
     601                 :            :     }
     602                 :            : 
     603                 :            :     double m2;
     604         [ -  + ]:         16 :     m2 = mab < mcd ? mab : mcd;
     605         [ -  + ]:         16 :     m2 = m2 < mef ? m2 : mef;
     606         [ -  + ]:         16 :     m2 = m2 < mgh ? m2 : mgh;
     607         [ -  + ]:         16 :     m2 = m2 < mij ? m2 : mij;
     608         [ -  + ]:         16 :     m2 = m2 < mkl ? m2 : mkl;
     609                 :            : 
     610         [ -  + ]:         16 :     if( m2 < VERDICT_DBL_MIN ) return (double)VERDICT_DBL_MAX;
     611                 :            : 
     612                 :            :     double M2;
     613         [ -  + ]:         16 :     M2 = Mab > Mcd ? Mab : Mcd;
     614         [ -  + ]:         16 :     M2 = M2 > Mef ? M2 : Mef;
     615         [ -  + ]:         16 :     M2 = M2 > Mgh ? M2 : Mgh;
     616         [ -  + ]:         16 :     M2 = M2 > Mij ? M2 : Mij;
     617         [ -  + ]:         16 :     M2 = M2 > Mkl ? M2 : Mkl;
     618         [ -  + ]:         16 :     m2 = m2 < mef ? m2 : mef;
     619                 :            : 
     620         [ -  + ]:         16 :     M2 = Mab > Mcd ? Mab : Mcd;
     621         [ -  + ]:         16 :     M2 = M2 > Mef ? M2 : Mef;
     622                 :            : 
     623                 :         16 :     double edge_ratio = sqrt( M2 / m2 );
     624                 :            : 
     625 [ +  - ][ +  - ]:         16 :     if( edge_ratio > 0 ) return (double)VERDICT_MIN( edge_ratio, VERDICT_DBL_MAX );
     626         [ #  # ]:         16 :     return (double)VERDICT_MAX( edge_ratio, -VERDICT_DBL_MAX );
     627                 :            : }
     628                 :            : 
     629                 :            : /*!
     630                 :            :   max edge ratio of a hex
     631                 :            : 
     632                 :            :   Maximum edge length ratio at hex center
     633                 :            : */
     634                 :          8 : C_FUNC_DEF double v_hex_max_edge_ratio( int /*num_nodes*/, double coordinates[][3] )
     635                 :            : {
     636                 :            :     double aspect;
     637 [ +  - ][ +  + ]:         72 :     VerdictVector node_pos[8];
     638 [ +  - ][ +  + ]:         72 :     make_hex_nodes( coordinates, node_pos );
     639                 :            : 
     640                 :            :     double aspect_12, aspect_13, aspect_23;
     641                 :            : 
     642         [ +  - ]:          8 :     VerdictVector efg1 = calc_hex_efg( 1, node_pos );
     643         [ +  - ]:          8 :     VerdictVector efg2 = calc_hex_efg( 2, node_pos );
     644         [ +  - ]:          8 :     VerdictVector efg3 = calc_hex_efg( 3, node_pos );
     645                 :            : 
     646         [ +  - ]:          8 :     double mag_efg1 = efg1.length();
     647         [ +  - ]:          8 :     double mag_efg2 = efg2.length();
     648         [ +  - ]:          8 :     double mag_efg3 = efg3.length();
     649                 :            : 
     650 [ -  + ][ -  + ]:          8 :     aspect_12 = safe_ratio( VERDICT_MAX( mag_efg1, mag_efg2 ), VERDICT_MIN( mag_efg1, mag_efg2 ) );
                 [ +  - ]
     651 [ -  + ][ -  + ]:          8 :     aspect_13 = safe_ratio( VERDICT_MAX( mag_efg1, mag_efg3 ), VERDICT_MIN( mag_efg1, mag_efg3 ) );
                 [ +  - ]
     652 [ -  + ][ -  + ]:          8 :     aspect_23 = safe_ratio( VERDICT_MAX( mag_efg2, mag_efg3 ), VERDICT_MIN( mag_efg2, mag_efg3 ) );
                 [ +  - ]
     653                 :            : 
     654 [ -  + ][ -  + ]:          8 :     aspect = VERDICT_MAX( aspect_12, VERDICT_MAX( aspect_13, aspect_23 ) );
                 [ -  + ]
     655                 :            : 
     656 [ +  - ][ +  - ]:          8 :     if( aspect > 0 ) return (double)VERDICT_MIN( aspect, VERDICT_DBL_MAX );
     657         [ #  # ]:          8 :     return (double)VERDICT_MAX( aspect, -VERDICT_DBL_MAX );
     658                 :            : }
     659                 :            : 
     660                 :            : /*!
     661                 :            :   skew of a hex
     662                 :            : 
     663                 :            :   Maximum ||cosA|| where A is the angle between edges at hex center.
     664                 :            : */
     665                 :          9 : C_FUNC_DEF double v_hex_skew( int /*num_nodes*/, double coordinates[][3] )
     666                 :            : {
     667 [ +  - ][ +  + ]:         81 :     VerdictVector node_pos[8];
     668 [ +  - ][ +  + ]:         81 :     make_hex_nodes( coordinates, node_pos );
     669                 :            : 
     670                 :            :     double skew_1, skew_2, skew_3;
     671                 :            : 
     672         [ +  - ]:          9 :     VerdictVector efg1 = calc_hex_efg( 1, node_pos );
     673         [ +  - ]:          9 :     VerdictVector efg2 = calc_hex_efg( 2, node_pos );
     674         [ +  - ]:          9 :     VerdictVector efg3 = calc_hex_efg( 3, node_pos );
     675                 :            : 
     676 [ +  - ][ -  + ]:          9 :     if( efg1.normalize() <= VERDICT_DBL_MIN ) return VERDICT_DBL_MAX;
     677 [ +  - ][ -  + ]:          9 :     if( efg2.normalize() <= VERDICT_DBL_MIN ) return VERDICT_DBL_MAX;
     678 [ +  - ][ -  + ]:          9 :     if( efg3.normalize() <= VERDICT_DBL_MIN ) return VERDICT_DBL_MAX;
     679                 :            : 
     680         [ +  - ]:          9 :     skew_1 = fabs( efg1 % efg2 );
     681         [ +  - ]:          9 :     skew_2 = fabs( efg1 % efg3 );
     682         [ +  - ]:          9 :     skew_3 = fabs( efg2 % efg3 );
     683                 :            : 
     684 [ +  + ][ -  + ]:          9 :     double skew = ( VERDICT_MAX( skew_1, VERDICT_MAX( skew_2, skew_3 ) ) );
                 [ +  + ]
     685                 :            : 
     686 [ +  + ][ +  - ]:          9 :     if( skew > 0 ) return (double)VERDICT_MIN( skew, VERDICT_DBL_MAX );
     687         [ +  - ]:          9 :     return (double)VERDICT_MAX( skew, -VERDICT_DBL_MAX );
     688                 :            : }
     689                 :            : 
     690                 :            : /*!
     691                 :            :   taper of a hex
     692                 :            : 
     693                 :            :   Maximum ratio of lengths derived from opposite edges.
     694                 :            : */
     695                 :          9 : C_FUNC_DEF double v_hex_taper( int /*num_nodes*/, double coordinates[][3] )
     696                 :            : {
     697 [ +  - ][ +  + ]:         81 :     VerdictVector node_pos[8];
     698 [ +  - ][ +  + ]:         81 :     make_hex_nodes( coordinates, node_pos );
     699                 :            : 
     700         [ +  - ]:          9 :     VerdictVector efg1 = calc_hex_efg( 1, node_pos );
     701         [ +  - ]:          9 :     VerdictVector efg2 = calc_hex_efg( 2, node_pos );
     702         [ +  - ]:          9 :     VerdictVector efg3 = calc_hex_efg( 3, node_pos );
     703                 :            : 
     704         [ +  - ]:          9 :     VerdictVector efg12 = calc_hex_efg( 12, node_pos );
     705         [ +  - ]:          9 :     VerdictVector efg13 = calc_hex_efg( 13, node_pos );
     706         [ +  - ]:          9 :     VerdictVector efg23 = calc_hex_efg( 23, node_pos );
     707                 :            : 
     708 [ +  - ][ +  - ]:          9 :     double taper_1 = fabs( safe_ratio( efg12.length(), VERDICT_MIN( efg1.length(), efg2.length() ) ) );
         [ -  + ][ #  # ]
         [ +  - ][ +  - ]
                 [ +  - ]
     709 [ +  - ][ +  - ]:          9 :     double taper_2 = fabs( safe_ratio( efg13.length(), VERDICT_MIN( efg1.length(), efg3.length() ) ) );
         [ -  + ][ #  # ]
         [ +  - ][ +  - ]
                 [ +  - ]
     710 [ +  - ][ +  - ]:          9 :     double taper_3 = fabs( safe_ratio( efg23.length(), VERDICT_MIN( efg2.length(), efg3.length() ) ) );
         [ -  + ][ #  # ]
         [ +  - ][ +  - ]
                 [ +  - ]
     711                 :            : 
     712 [ +  + ][ -  + ]:          9 :     double taper = (double)VERDICT_MAX( taper_1, VERDICT_MAX( taper_2, taper_3 ) );
                 [ +  + ]
     713                 :            : 
     714 [ +  + ][ +  - ]:          9 :     if( taper > 0 ) return (double)VERDICT_MIN( taper, VERDICT_DBL_MAX );
     715         [ +  - ]:          9 :     return (double)VERDICT_MAX( taper, -VERDICT_DBL_MAX );
     716                 :            : }
     717                 :            : 
     718                 :            : /*!
     719                 :            :   volume of a hex
     720                 :            : 
     721                 :            :   Jacobian at hex center
     722                 :            : */
     723                 :         17 : C_FUNC_DEF double v_hex_volume( int /*num_nodes*/, double coordinates[][3] )
     724                 :            : {
     725 [ +  - ][ +  + ]:        153 :     VerdictVector node_pos[8];
     726 [ +  - ][ +  + ]:        153 :     make_hex_nodes( coordinates, node_pos );
     727                 :            : 
     728         [ +  - ]:         17 :     VerdictVector efg1 = calc_hex_efg( 1, node_pos );
     729         [ +  - ]:         17 :     VerdictVector efg2 = calc_hex_efg( 2, node_pos );
     730         [ +  - ]:         17 :     VerdictVector efg3 = calc_hex_efg( 3, node_pos );
     731                 :            : 
     732                 :            :     double volume;
     733 [ +  - ][ +  - ]:         17 :     volume = (double)( efg1 % ( efg2 * efg3 ) ) / 64.0;
     734                 :            : 
     735 [ +  - ][ +  - ]:         17 :     if( volume > 0 ) return (double)VERDICT_MIN( volume, VERDICT_DBL_MAX );
     736         [ #  # ]:         17 :     return (double)VERDICT_MAX( volume, -VERDICT_DBL_MAX );
     737                 :            : }
     738                 :            : 
     739                 :            : /*!
     740                 :            :   stretch of a hex
     741                 :            : 
     742                 :            :   sqrt(3) * minimum edge length / maximum diagonal length
     743                 :            : */
     744                 :          9 : C_FUNC_DEF double v_hex_stretch( int /*num_nodes*/, double coordinates[][3] )
     745                 :            : {
     746                 :            :     static const double HEX_STRETCH_SCALE_FACTOR = sqrt( 3.0 );
     747                 :            : 
     748                 :          9 :     double min_edge = hex_edge_length( 0, coordinates );
     749                 :          9 :     double max_diag = diag_length( 1, coordinates );
     750                 :            : 
     751                 :          9 :     double stretch = HEX_STRETCH_SCALE_FACTOR * safe_ratio( min_edge, max_diag );
     752                 :            : 
     753 [ +  - ][ +  - ]:          9 :     if( stretch > 0 ) return (double)VERDICT_MIN( stretch, VERDICT_DBL_MAX );
     754         [ #  # ]:          0 :     return (double)VERDICT_MAX( stretch, -VERDICT_DBL_MAX );
     755                 :            : }
     756                 :            : 
     757                 :            : /*!
     758                 :            :   diagonal ratio of a hex
     759                 :            : 
     760                 :            :   Minimum diagonal length / maximum diagonal length
     761                 :            : */
     762                 :         17 : C_FUNC_DEF double v_hex_diagonal( int /*num_nodes*/, double coordinates[][3] )
     763                 :            : {
     764                 :            : 
     765                 :         17 :     double min_diag = diag_length( 0, coordinates );
     766                 :         17 :     double max_diag = diag_length( 1, coordinates );
     767                 :            : 
     768                 :         17 :     double diagonal = safe_ratio( min_diag, max_diag );
     769                 :            : 
     770 [ +  - ][ +  - ]:         17 :     if( diagonal > 0 ) return (double)VERDICT_MIN( diagonal, VERDICT_DBL_MAX );
     771         [ #  # ]:          0 :     return (double)VERDICT_MAX( diagonal, -VERDICT_DBL_MAX );
     772                 :            : }
     773                 :            : 
     774                 :            : #define SQR( x ) ( ( x ) * ( x ) )
     775                 :            : 
     776                 :            : /*!
     777                 :            :   dimension of a hex
     778                 :            : 
     779                 :            :   Pronto-specific characteristic length for stable time step calculation.
     780                 :            :   Char_length = Volume / 2 grad Volume
     781                 :            : */
     782                 :         17 : C_FUNC_DEF double v_hex_dimension( int /*num_nodes*/, double coordinates[][3] )
     783                 :            : {
     784                 :            : 
     785                 :            :     double gradop[9][4];
     786                 :            : 
     787                 :         17 :     double x1 = coordinates[0][0];
     788                 :         17 :     double x2 = coordinates[1][0];
     789                 :         17 :     double x3 = coordinates[2][0];
     790                 :         17 :     double x4 = coordinates[3][0];
     791                 :         17 :     double x5 = coordinates[4][0];
     792                 :         17 :     double x6 = coordinates[5][0];
     793                 :         17 :     double x7 = coordinates[6][0];
     794                 :         17 :     double x8 = coordinates[7][0];
     795                 :            : 
     796                 :         17 :     double y1 = coordinates[0][1];
     797                 :         17 :     double y2 = coordinates[1][1];
     798                 :         17 :     double y3 = coordinates[2][1];
     799                 :         17 :     double y4 = coordinates[3][1];
     800                 :         17 :     double y5 = coordinates[4][1];
     801                 :         17 :     double y6 = coordinates[5][1];
     802                 :         17 :     double y7 = coordinates[6][1];
     803                 :         17 :     double y8 = coordinates[7][1];
     804                 :            : 
     805                 :         17 :     double z1 = coordinates[0][2];
     806                 :         17 :     double z2 = coordinates[1][2];
     807                 :         17 :     double z3 = coordinates[2][2];
     808                 :         17 :     double z4 = coordinates[3][2];
     809                 :         17 :     double z5 = coordinates[4][2];
     810                 :         17 :     double z6 = coordinates[5][2];
     811                 :         17 :     double z7 = coordinates[6][2];
     812                 :         17 :     double z8 = coordinates[7][2];
     813                 :            : 
     814                 :         17 :     double z24 = z2 - z4;
     815                 :         17 :     double z52 = z5 - z2;
     816                 :         17 :     double z45 = z4 - z5;
     817                 :            :     gradop[1][1] =
     818                 :         17 :         ( y2 * ( z6 - z3 - z45 ) + y3 * z24 + y4 * ( z3 - z8 - z52 ) + y5 * ( z8 - z6 - z24 ) + y6 * z52 + y8 * z45 ) /
     819                 :         17 :         12.0;
     820                 :            : 
     821                 :         17 :     double z31 = z3 - z1;
     822                 :         17 :     double z63 = z6 - z3;
     823                 :         17 :     double z16 = z1 - z6;
     824                 :            :     gradop[2][1] =
     825                 :         17 :         ( y3 * ( z7 - z4 - z16 ) + y4 * z31 + y1 * ( z4 - z5 - z63 ) + y6 * ( z5 - z7 - z31 ) + y7 * z63 + y5 * z16 ) /
     826                 :         17 :         12.0;
     827                 :            : 
     828                 :         17 :     double z42 = z4 - z2;
     829                 :         17 :     double z74 = z7 - z4;
     830                 :         17 :     double z27 = z2 - z7;
     831                 :            :     gradop[3][1] =
     832                 :         17 :         ( y4 * ( z8 - z1 - z27 ) + y1 * z42 + y2 * ( z1 - z6 - z74 ) + y7 * ( z6 - z8 - z42 ) + y8 * z74 + y6 * z27 ) /
     833                 :         17 :         12.0;
     834                 :            : 
     835                 :         17 :     double z13 = z1 - z3;
     836                 :         17 :     double z81 = z8 - z1;
     837                 :         17 :     double z38 = z3 - z8;
     838                 :            :     gradop[4][1] =
     839                 :         17 :         ( y1 * ( z5 - z2 - z38 ) + y2 * z13 + y3 * ( z2 - z7 - z81 ) + y8 * ( z7 - z5 - z13 ) + y5 * z81 + y7 * z38 ) /
     840                 :         17 :         12.0;
     841                 :            : 
     842                 :         17 :     double z86 = z8 - z6;
     843                 :         17 :     double z18 = z1 - z8;
     844                 :         17 :     double z61 = z6 - z1;
     845                 :            :     gradop[5][1] =
     846                 :         17 :         ( y8 * ( z4 - z7 - z61 ) + y7 * z86 + y6 * ( z7 - z2 - z18 ) + y1 * ( z2 - z4 - z86 ) + y4 * z18 + y2 * z61 ) /
     847                 :         17 :         12.0;
     848                 :            : 
     849                 :         17 :     double z57 = z5 - z7;
     850                 :         17 :     double z25 = z2 - z5;
     851                 :         17 :     double z72 = z7 - z2;
     852                 :            :     gradop[6][1] =
     853                 :         17 :         ( y5 * ( z1 - z8 - z72 ) + y8 * z57 + y7 * ( z8 - z3 - z25 ) + y2 * ( z3 - z1 - z57 ) + y1 * z25 + y3 * z72 ) /
     854                 :         17 :         12.0;
     855                 :            : 
     856                 :         17 :     double z68 = z6 - z8;
     857                 :         17 :     double z36 = z3 - z6;
     858                 :         17 :     double z83 = z8 - z3;
     859                 :            :     gradop[7][1] =
     860                 :         17 :         ( y6 * ( z2 - z5 - z83 ) + y5 * z68 + y8 * ( z5 - z4 - z36 ) + y3 * ( z4 - z2 - z68 ) + y2 * z36 + y4 * z83 ) /
     861                 :         17 :         12.0;
     862                 :            : 
     863                 :         17 :     double z75 = z7 - z5;
     864                 :         17 :     double z47 = z4 - z7;
     865                 :         17 :     double z54 = z5 - z4;
     866                 :            :     gradop[8][1] =
     867                 :         17 :         ( y7 * ( z3 - z6 - z54 ) + y6 * z75 + y5 * ( z6 - z1 - z47 ) + y4 * ( z1 - z3 - z75 ) + y3 * z47 + y1 * z54 ) /
     868                 :         17 :         12.0;
     869                 :            : 
     870                 :         17 :     double x24 = x2 - x4;
     871                 :         17 :     double x52 = x5 - x2;
     872                 :         17 :     double x45 = x4 - x5;
     873                 :            :     gradop[1][2] =
     874                 :         17 :         ( z2 * ( x6 - x3 - x45 ) + z3 * x24 + z4 * ( x3 - x8 - x52 ) + z5 * ( x8 - x6 - x24 ) + z6 * x52 + z8 * x45 ) /
     875                 :         17 :         12.0;
     876                 :            : 
     877                 :         17 :     double x31 = x3 - x1;
     878                 :         17 :     double x63 = x6 - x3;
     879                 :         17 :     double x16 = x1 - x6;
     880                 :            :     gradop[2][2] =
     881                 :         17 :         ( z3 * ( x7 - x4 - x16 ) + z4 * x31 + z1 * ( x4 - x5 - x63 ) + z6 * ( x5 - x7 - x31 ) + z7 * x63 + z5 * x16 ) /
     882                 :         17 :         12.0;
     883                 :            : 
     884                 :         17 :     double x42 = x4 - x2;
     885                 :         17 :     double x74 = x7 - x4;
     886                 :         17 :     double x27 = x2 - x7;
     887                 :            :     gradop[3][2] =
     888                 :         17 :         ( z4 * ( x8 - x1 - x27 ) + z1 * x42 + z2 * ( x1 - x6 - x74 ) + z7 * ( x6 - x8 - x42 ) + z8 * x74 + z6 * x27 ) /
     889                 :         17 :         12.0;
     890                 :            : 
     891                 :         17 :     double x13 = x1 - x3;
     892                 :         17 :     double x81 = x8 - x1;
     893                 :         17 :     double x38 = x3 - x8;
     894                 :            :     gradop[4][2] =
     895                 :         17 :         ( z1 * ( x5 - x2 - x38 ) + z2 * x13 + z3 * ( x2 - x7 - x81 ) + z8 * ( x7 - x5 - x13 ) + z5 * x81 + z7 * x38 ) /
     896                 :         17 :         12.0;
     897                 :            : 
     898                 :         17 :     double x86 = x8 - x6;
     899                 :         17 :     double x18 = x1 - x8;
     900                 :         17 :     double x61 = x6 - x1;
     901                 :            :     gradop[5][2] =
     902                 :         17 :         ( z8 * ( x4 - x7 - x61 ) + z7 * x86 + z6 * ( x7 - x2 - x18 ) + z1 * ( x2 - x4 - x86 ) + z4 * x18 + z2 * x61 ) /
     903                 :         17 :         12.0;
     904                 :            : 
     905                 :         17 :     double x57 = x5 - x7;
     906                 :         17 :     double x25 = x2 - x5;
     907                 :         17 :     double x72 = x7 - x2;
     908                 :            :     gradop[6][2] =
     909                 :         17 :         ( z5 * ( x1 - x8 - x72 ) + z8 * x57 + z7 * ( x8 - x3 - x25 ) + z2 * ( x3 - x1 - x57 ) + z1 * x25 + z3 * x72 ) /
     910                 :         17 :         12.0;
     911                 :            : 
     912                 :         17 :     double x68 = x6 - x8;
     913                 :         17 :     double x36 = x3 - x6;
     914                 :         17 :     double x83 = x8 - x3;
     915                 :            :     gradop[7][2] =
     916                 :         17 :         ( z6 * ( x2 - x5 - x83 ) + z5 * x68 + z8 * ( x5 - x4 - x36 ) + z3 * ( x4 - x2 - x68 ) + z2 * x36 + z4 * x83 ) /
     917                 :         17 :         12.0;
     918                 :            : 
     919                 :         17 :     double x75 = x7 - x5;
     920                 :         17 :     double x47 = x4 - x7;
     921                 :         17 :     double x54 = x5 - x4;
     922                 :            :     gradop[8][2] =
     923                 :         17 :         ( z7 * ( x3 - x6 - x54 ) + z6 * x75 + z5 * ( x6 - x1 - x47 ) + z4 * ( x1 - x3 - x75 ) + z3 * x47 + z1 * x54 ) /
     924                 :         17 :         12.0;
     925                 :            : 
     926                 :         17 :     double y24 = y2 - y4;
     927                 :         17 :     double y52 = y5 - y2;
     928                 :         17 :     double y45 = y4 - y5;
     929                 :            :     gradop[1][3] =
     930                 :         17 :         ( x2 * ( y6 - y3 - y45 ) + x3 * y24 + x4 * ( y3 - y8 - y52 ) + x5 * ( y8 - y6 - y24 ) + x6 * y52 + x8 * y45 ) /
     931                 :         17 :         12.0;
     932                 :            : 
     933                 :         17 :     double y31 = y3 - y1;
     934                 :         17 :     double y63 = y6 - y3;
     935                 :         17 :     double y16 = y1 - y6;
     936                 :            :     gradop[2][3] =
     937                 :         17 :         ( x3 * ( y7 - y4 - y16 ) + x4 * y31 + x1 * ( y4 - y5 - y63 ) + x6 * ( y5 - y7 - y31 ) + x7 * y63 + x5 * y16 ) /
     938                 :         17 :         12.0;
     939                 :            : 
     940                 :         17 :     double y42 = y4 - y2;
     941                 :         17 :     double y74 = y7 - y4;
     942                 :         17 :     double y27 = y2 - y7;
     943                 :            :     gradop[3][3] =
     944                 :         17 :         ( x4 * ( y8 - y1 - y27 ) + x1 * y42 + x2 * ( y1 - y6 - y74 ) + x7 * ( y6 - y8 - y42 ) + x8 * y74 + x6 * y27 ) /
     945                 :         17 :         12.0;
     946                 :            : 
     947                 :         17 :     double y13 = y1 - y3;
     948                 :         17 :     double y81 = y8 - y1;
     949                 :         17 :     double y38 = y3 - y8;
     950                 :            :     gradop[4][3] =
     951                 :         17 :         ( x1 * ( y5 - y2 - y38 ) + x2 * y13 + x3 * ( y2 - y7 - y81 ) + x8 * ( y7 - y5 - y13 ) + x5 * y81 + x7 * y38 ) /
     952                 :         17 :         12.0;
     953                 :            : 
     954                 :         17 :     double y86 = y8 - y6;
     955                 :         17 :     double y18 = y1 - y8;
     956                 :         17 :     double y61 = y6 - y1;
     957                 :            :     gradop[5][3] =
     958                 :         17 :         ( x8 * ( y4 - y7 - y61 ) + x7 * y86 + x6 * ( y7 - y2 - y18 ) + x1 * ( y2 - y4 - y86 ) + x4 * y18 + x2 * y61 ) /
     959                 :         17 :         12.0;
     960                 :            : 
     961                 :         17 :     double y57 = y5 - y7;
     962                 :         17 :     double y25 = y2 - y5;
     963                 :         17 :     double y72 = y7 - y2;
     964                 :            :     gradop[6][3] =
     965                 :         17 :         ( x5 * ( y1 - y8 - y72 ) + x8 * y57 + x7 * ( y8 - y3 - y25 ) + x2 * ( y3 - y1 - y57 ) + x1 * y25 + x3 * y72 ) /
     966                 :         17 :         12.0;
     967                 :            : 
     968                 :         17 :     double y68 = y6 - y8;
     969                 :         17 :     double y36 = y3 - y6;
     970                 :         17 :     double y83 = y8 - y3;
     971                 :            :     gradop[7][3] =
     972                 :         17 :         ( x6 * ( y2 - y5 - y83 ) + x5 * y68 + x8 * ( y5 - y4 - y36 ) + x3 * ( y4 - y2 - y68 ) + x2 * y36 + x4 * y83 ) /
     973                 :         17 :         12.0;
     974                 :            : 
     975                 :         17 :     double y75 = y7 - y5;
     976                 :         17 :     double y47 = y4 - y7;
     977                 :         17 :     double y54 = y5 - y4;
     978                 :            :     gradop[8][3] =
     979                 :         17 :         ( x7 * ( y3 - y6 - y54 ) + x6 * y75 + x5 * ( y6 - y1 - y47 ) + x4 * ( y1 - y3 - y75 ) + x3 * y47 + x1 * y54 ) /
     980                 :         17 :         12.0;
     981                 :            : 
     982                 :            :     //     calculate element volume and characteristic element aspect ratio
     983                 :            :     //     (used in time step and hourglass control) -
     984                 :            : 
     985                 :         34 :     double volume = coordinates[0][0] * gradop[1][1] + coordinates[1][0] * gradop[2][1] +
     986                 :         51 :                     coordinates[2][0] * gradop[3][1] + coordinates[3][0] * gradop[4][1] +
     987                 :         51 :                     coordinates[4][0] * gradop[5][1] + coordinates[5][0] * gradop[6][1] +
     988                 :         34 :                     coordinates[6][0] * gradop[7][1] + coordinates[7][0] * gradop[8][1];
     989                 :            :     double aspect =
     990                 :         17 :         .5 * SQR( volume ) /
     991                 :         34 :         ( SQR( gradop[1][1] ) + SQR( gradop[2][1] ) + SQR( gradop[3][1] ) + SQR( gradop[4][1] ) + SQR( gradop[5][1] ) +
     992                 :         51 :           SQR( gradop[6][1] ) + SQR( gradop[7][1] ) + SQR( gradop[8][1] ) + SQR( gradop[1][2] ) + SQR( gradop[2][2] ) +
     993                 :         51 :           SQR( gradop[3][2] ) + SQR( gradop[4][2] ) + SQR( gradop[5][2] ) + SQR( gradop[6][2] ) + SQR( gradop[7][2] ) +
     994                 :         51 :           SQR( gradop[8][2] ) + SQR( gradop[1][3] ) + SQR( gradop[2][3] ) + SQR( gradop[3][3] ) + SQR( gradop[4][3] ) +
     995                 :         34 :           SQR( gradop[5][3] ) + SQR( gradop[6][3] ) + SQR( gradop[7][3] ) + SQR( gradop[8][3] ) );
     996                 :            : 
     997                 :         17 :     return (double)sqrt( aspect );
     998                 :            : }
     999                 :            : 
    1000                 :            : /*!
    1001                 :            :   oddy of a hex
    1002                 :            : 
    1003                 :            :   General distortion measure based on left Cauchy-Green Tensor
    1004                 :            : */
    1005                 :          8 : C_FUNC_DEF double v_hex_oddy( int /*num_nodes*/, double coordinates[][3] )
    1006                 :            : {
    1007                 :            : 
    1008                 :          8 :     double oddy = 0.0, current_oddy;
    1009 [ +  - ][ +  - ]:          8 :     VerdictVector xxi, xet, xze;
                 [ +  - ]
    1010                 :            : 
    1011 [ +  - ][ +  + ]:         72 :     VerdictVector node_pos[8];
    1012 [ +  - ][ +  + ]:         72 :     make_hex_nodes( coordinates, node_pos );
    1013                 :            : 
    1014 [ +  - ][ +  - ]:          8 :     xxi = calc_hex_efg( 1, node_pos );
    1015 [ +  - ][ +  - ]:          8 :     xet = calc_hex_efg( 2, node_pos );
    1016 [ +  - ][ +  - ]:          8 :     xze = calc_hex_efg( 3, node_pos );
    1017                 :            : 
    1018         [ +  - ]:          8 :     current_oddy = oddy_comp( xxi, xet, xze );
    1019         [ -  + ]:          8 :     if( current_oddy > oddy ) { oddy = current_oddy; }
    1020                 :            : 
    1021                 :         16 :     xxi.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
    1022         [ +  - ]:          8 :              coordinates[1][2] - coordinates[0][2] );
    1023                 :            : 
    1024                 :         16 :     xet.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
    1025         [ +  - ]:          8 :              coordinates[3][2] - coordinates[0][2] );
    1026                 :            : 
    1027                 :         16 :     xze.set( coordinates[4][0] - coordinates[0][0], coordinates[4][1] - coordinates[0][1],
    1028         [ +  - ]:          8 :              coordinates[4][2] - coordinates[0][2] );
    1029                 :            : 
    1030         [ +  - ]:          8 :     current_oddy = oddy_comp( xxi, xet, xze );
    1031         [ -  + ]:          8 :     if( current_oddy > oddy ) { oddy = current_oddy; }
    1032                 :            : 
    1033                 :         16 :     xxi.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
    1034         [ +  - ]:          8 :              coordinates[2][2] - coordinates[1][2] );
    1035                 :            : 
    1036                 :         16 :     xet.set( coordinates[0][0] - coordinates[1][0], coordinates[0][1] - coordinates[1][1],
    1037         [ +  - ]:          8 :              coordinates[0][2] - coordinates[1][2] );
    1038                 :            : 
    1039                 :         16 :     xze.set( coordinates[5][0] - coordinates[1][0], coordinates[5][1] - coordinates[1][1],
    1040         [ +  - ]:          8 :              coordinates[5][2] - coordinates[1][2] );
    1041                 :            : 
    1042         [ +  - ]:          8 :     current_oddy = oddy_comp( xxi, xet, xze );
    1043         [ -  + ]:          8 :     if( current_oddy > oddy ) { oddy = current_oddy; }
    1044                 :            : 
    1045                 :         16 :     xxi.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
    1046         [ +  - ]:          8 :              coordinates[3][2] - coordinates[2][2] );
    1047                 :            : 
    1048                 :         16 :     xet.set( coordinates[1][0] - coordinates[2][0], coordinates[1][1] - coordinates[2][1],
    1049         [ +  - ]:          8 :              coordinates[1][2] - coordinates[2][2] );
    1050                 :            : 
    1051                 :         16 :     xze.set( coordinates[6][0] - coordinates[2][0], coordinates[6][1] - coordinates[2][1],
    1052         [ +  - ]:          8 :              coordinates[6][2] - coordinates[2][2] );
    1053                 :            : 
    1054         [ +  - ]:          8 :     current_oddy = oddy_comp( xxi, xet, xze );
    1055         [ -  + ]:          8 :     if( current_oddy > oddy ) { oddy = current_oddy; }
    1056                 :            : 
    1057                 :         16 :     xxi.set( coordinates[0][0] - coordinates[3][0], coordinates[0][1] - coordinates[3][1],
    1058         [ +  - ]:          8 :              coordinates[0][2] - coordinates[3][2] );
    1059                 :            : 
    1060                 :         16 :     xet.set( coordinates[2][0] - coordinates[3][0], coordinates[2][1] - coordinates[3][1],
    1061         [ +  - ]:          8 :              coordinates[2][2] - coordinates[3][2] );
    1062                 :            : 
    1063                 :         16 :     xze.set( coordinates[7][0] - coordinates[3][0], coordinates[7][1] - coordinates[3][1],
    1064         [ +  - ]:          8 :              coordinates[7][2] - coordinates[3][2] );
    1065                 :            : 
    1066         [ +  - ]:          8 :     current_oddy = oddy_comp( xxi, xet, xze );
    1067         [ -  + ]:          8 :     if( current_oddy > oddy ) { oddy = current_oddy; }
    1068                 :            : 
    1069                 :         16 :     xxi.set( coordinates[7][0] - coordinates[4][0], coordinates[7][1] - coordinates[4][1],
    1070         [ +  - ]:          8 :              coordinates[7][2] - coordinates[4][2] );
    1071                 :            : 
    1072                 :         16 :     xet.set( coordinates[5][0] - coordinates[4][0], coordinates[5][1] - coordinates[4][1],
    1073         [ +  - ]:          8 :              coordinates[5][2] - coordinates[4][2] );
    1074                 :            : 
    1075                 :         16 :     xze.set( coordinates[0][0] - coordinates[4][0], coordinates[0][1] - coordinates[4][1],
    1076         [ +  - ]:          8 :              coordinates[0][2] - coordinates[4][2] );
    1077                 :            : 
    1078         [ +  - ]:          8 :     current_oddy = oddy_comp( xxi, xet, xze );
    1079         [ -  + ]:          8 :     if( current_oddy > oddy ) { oddy = current_oddy; }
    1080                 :            : 
    1081                 :         16 :     xxi.set( coordinates[4][0] - coordinates[5][0], coordinates[4][1] - coordinates[5][1],
    1082         [ +  - ]:          8 :              coordinates[4][2] - coordinates[5][2] );
    1083                 :            : 
    1084                 :         16 :     xet.set( coordinates[6][0] - coordinates[5][0], coordinates[6][1] - coordinates[5][1],
    1085         [ +  - ]:          8 :              coordinates[6][2] - coordinates[5][2] );
    1086                 :            : 
    1087                 :         16 :     xze.set( coordinates[1][0] - coordinates[5][0], coordinates[1][1] - coordinates[5][1],
    1088         [ +  - ]:          8 :              coordinates[1][2] - coordinates[5][2] );
    1089                 :            : 
    1090         [ +  - ]:          8 :     current_oddy = oddy_comp( xxi, xet, xze );
    1091         [ -  + ]:          8 :     if( current_oddy > oddy ) { oddy = current_oddy; }
    1092                 :            : 
    1093                 :         16 :     xxi.set( coordinates[5][0] - coordinates[6][0], coordinates[5][1] - coordinates[6][1],
    1094         [ +  - ]:          8 :              coordinates[5][2] - coordinates[6][2] );
    1095                 :            : 
    1096                 :         16 :     xet.set( coordinates[7][0] - coordinates[6][0], coordinates[7][1] - coordinates[6][1],
    1097         [ +  - ]:          8 :              coordinates[7][2] - coordinates[6][2] );
    1098                 :            : 
    1099                 :         16 :     xze.set( coordinates[2][0] - coordinates[6][0], coordinates[2][1] - coordinates[6][1],
    1100         [ +  - ]:          8 :              coordinates[2][2] - coordinates[6][2] );
    1101                 :            : 
    1102         [ +  - ]:          8 :     current_oddy = oddy_comp( xxi, xet, xze );
    1103         [ -  + ]:          8 :     if( current_oddy > oddy ) { oddy = current_oddy; }
    1104                 :            : 
    1105                 :         16 :     xxi.set( coordinates[6][0] - coordinates[7][0], coordinates[6][1] - coordinates[7][1],
    1106         [ +  - ]:          8 :              coordinates[6][2] - coordinates[7][2] );
    1107                 :            : 
    1108                 :         16 :     xet.set( coordinates[4][0] - coordinates[7][0], coordinates[4][1] - coordinates[7][1],
    1109         [ +  - ]:          8 :              coordinates[4][2] - coordinates[7][2] );
    1110                 :            : 
    1111                 :         16 :     xze.set( coordinates[3][0] - coordinates[7][0], coordinates[3][1] - coordinates[7][1],
    1112         [ +  - ]:          8 :              coordinates[3][2] - coordinates[7][2] );
    1113                 :            : 
    1114         [ +  - ]:          8 :     current_oddy = oddy_comp( xxi, xet, xze );
    1115         [ -  + ]:          8 :     if( current_oddy > oddy ) { oddy = current_oddy; }
    1116                 :            : 
    1117 [ -  + ][ #  # ]:          8 :     if( oddy > 0 ) return (double)VERDICT_MIN( oddy, VERDICT_DBL_MAX );
    1118         [ +  - ]:          8 :     return (double)VERDICT_MAX( oddy, -VERDICT_DBL_MAX );
    1119                 :            : }
    1120                 :            : 
    1121                 :            : /*!
    1122                 :            :    the average Frobenius aspect of a hex
    1123                 :            : 
    1124                 :            :    NB (P. Pebay 01/20/07):
    1125                 :            :      this metric is calculated by averaging the 8 Frobenius aspects at
    1126                 :            :      each corner of the hex, when the reference corner is right isosceles.
    1127                 :            : */
    1128                 :         16 : C_FUNC_DEF double v_hex_med_aspect_frobenius( int /*num_nodes*/, double coordinates[][3] )
    1129                 :            : {
    1130                 :            : 
    1131 [ +  - ][ +  + ]:        144 :     VerdictVector node_pos[8];
    1132 [ +  - ][ +  + ]:        144 :     make_hex_nodes( coordinates, node_pos );
    1133                 :            : 
    1134                 :         16 :     double med_aspect_frobenius = 0.;
    1135 [ +  - ][ +  - ]:         16 :     VerdictVector xxi, xet, xze;
                 [ +  - ]
    1136                 :            : 
    1137                 :            :     // J(0,0,0):
    1138                 :            : 
    1139 [ +  - ][ +  - ]:         16 :     xxi = node_pos[1] - node_pos[0];
    1140 [ +  - ][ +  - ]:         16 :     xet = node_pos[3] - node_pos[0];
    1141 [ +  - ][ +  - ]:         16 :     xze = node_pos[4] - node_pos[0];
    1142                 :            : 
    1143         [ +  - ]:         16 :     med_aspect_frobenius += condition_comp( xxi, xet, xze );
    1144                 :            :     // J(1,0,0):
    1145                 :            : 
    1146 [ +  - ][ +  - ]:         16 :     xxi = node_pos[2] - node_pos[1];
    1147 [ +  - ][ +  - ]:         16 :     xet = node_pos[0] - node_pos[1];
    1148 [ +  - ][ +  - ]:         16 :     xze = node_pos[5] - node_pos[1];
    1149                 :            : 
    1150         [ +  - ]:         16 :     med_aspect_frobenius += condition_comp( xxi, xet, xze );
    1151                 :            :     // J(1,1,0):
    1152                 :            : 
    1153 [ +  - ][ +  - ]:         16 :     xxi = node_pos[3] - node_pos[2];
    1154 [ +  - ][ +  - ]:         16 :     xet = node_pos[1] - node_pos[2];
    1155 [ +  - ][ +  - ]:         16 :     xze = node_pos[6] - node_pos[2];
    1156                 :            : 
    1157         [ +  - ]:         16 :     med_aspect_frobenius += condition_comp( xxi, xet, xze );
    1158                 :            :     // J(0,1,0):
    1159                 :            : 
    1160 [ +  - ][ +  - ]:         16 :     xxi = node_pos[0] - node_pos[3];
    1161 [ +  - ][ +  - ]:         16 :     xet = node_pos[2] - node_pos[3];
    1162 [ +  - ][ +  - ]:         16 :     xze = node_pos[7] - node_pos[3];
    1163                 :            : 
    1164         [ +  - ]:         16 :     med_aspect_frobenius += condition_comp( xxi, xet, xze );
    1165                 :            :     // J(0,0,1):
    1166                 :            : 
    1167 [ +  - ][ +  - ]:         16 :     xxi = node_pos[7] - node_pos[4];
    1168 [ +  - ][ +  - ]:         16 :     xet = node_pos[5] - node_pos[4];
    1169 [ +  - ][ +  - ]:         16 :     xze = node_pos[0] - node_pos[4];
    1170                 :            : 
    1171         [ +  - ]:         16 :     med_aspect_frobenius += condition_comp( xxi, xet, xze );
    1172                 :            :     // J(1,0,1):
    1173                 :            : 
    1174 [ +  - ][ +  - ]:         16 :     xxi = node_pos[4] - node_pos[5];
    1175 [ +  - ][ +  - ]:         16 :     xet = node_pos[6] - node_pos[5];
    1176 [ +  - ][ +  - ]:         16 :     xze = node_pos[1] - node_pos[5];
    1177                 :            : 
    1178         [ +  - ]:         16 :     med_aspect_frobenius += condition_comp( xxi, xet, xze );
    1179                 :            :     // J(1,1,1):
    1180                 :            : 
    1181 [ +  - ][ +  - ]:         16 :     xxi = node_pos[5] - node_pos[6];
    1182 [ +  - ][ +  - ]:         16 :     xet = node_pos[7] - node_pos[6];
    1183 [ +  - ][ +  - ]:         16 :     xze = node_pos[2] - node_pos[6];
    1184                 :            : 
    1185         [ +  - ]:         16 :     med_aspect_frobenius += condition_comp( xxi, xet, xze );
    1186                 :            :     // J(1,1,1):
    1187                 :            : 
    1188 [ +  - ][ +  - ]:         16 :     xxi = node_pos[6] - node_pos[7];
    1189 [ +  - ][ +  - ]:         16 :     xet = node_pos[4] - node_pos[7];
    1190 [ +  - ][ +  - ]:         16 :     xze = node_pos[3] - node_pos[7];
    1191                 :            : 
    1192         [ +  - ]:         16 :     med_aspect_frobenius += condition_comp( xxi, xet, xze );
    1193                 :         16 :     med_aspect_frobenius /= 24.;
    1194                 :            : 
    1195 [ +  - ][ +  - ]:         16 :     if( med_aspect_frobenius > 0 ) return (double)VERDICT_MIN( med_aspect_frobenius, VERDICT_DBL_MAX );
    1196         [ #  # ]:         16 :     return (double)VERDICT_MAX( med_aspect_frobenius, -VERDICT_DBL_MAX );
    1197                 :            : }
    1198                 :            : 
    1199                 :            : /*!
    1200                 :            :   maximum Frobenius condition number of a hex
    1201                 :            : 
    1202                 :            :   Maximum Frobenius condition number of the Jacobian matrix at 8 corners
    1203                 :            :    NB (P. Pebay 01/25/07):
    1204                 :            :      this metric is calculated by taking the maximum of the 8 Frobenius aspects at
    1205                 :            :      each corner of the hex, when the reference corner is right isosceles.
    1206                 :            : */
    1207                 :         17 : C_FUNC_DEF double v_hex_max_aspect_frobenius( int /*num_nodes*/, double coordinates[][3] )
    1208                 :            : {
    1209                 :            : 
    1210 [ +  - ][ +  + ]:        153 :     VerdictVector node_pos[8];
    1211 [ +  - ][ +  + ]:        153 :     make_hex_nodes( coordinates, node_pos );
    1212                 :            : 
    1213                 :         17 :     double condition = 0.0, current_condition;
    1214 [ +  - ][ +  - ]:         17 :     VerdictVector xxi, xet, xze;
                 [ +  - ]
    1215                 :            : 
    1216 [ +  - ][ +  - ]:         17 :     xxi = calc_hex_efg( 1, node_pos );
    1217 [ +  - ][ +  - ]:         17 :     xet = calc_hex_efg( 2, node_pos );
    1218 [ +  - ][ +  - ]:         17 :     xze = calc_hex_efg( 3, node_pos );
    1219                 :            : 
    1220         [ +  - ]:         17 :     current_condition = condition_comp( xxi, xet, xze );
    1221         [ +  - ]:         17 :     if( current_condition > condition ) { condition = current_condition; }
    1222                 :            : 
    1223                 :            :     // J(0,0,0):
    1224                 :            : 
    1225 [ +  - ][ +  - ]:         17 :     xxi = node_pos[1] - node_pos[0];
    1226 [ +  - ][ +  - ]:         17 :     xet = node_pos[3] - node_pos[0];
    1227 [ +  - ][ +  - ]:         17 :     xze = node_pos[4] - node_pos[0];
    1228                 :            : 
    1229         [ +  - ]:         17 :     current_condition = condition_comp( xxi, xet, xze );
    1230         [ +  + ]:         17 :     if( current_condition > condition ) { condition = current_condition; }
    1231                 :            : 
    1232                 :            :     // J(1,0,0):
    1233                 :            : 
    1234 [ +  - ][ +  - ]:         17 :     xxi = node_pos[2] - node_pos[1];
    1235 [ +  - ][ +  - ]:         17 :     xet = node_pos[0] - node_pos[1];
    1236 [ +  - ][ +  - ]:         17 :     xze = node_pos[5] - node_pos[1];
    1237                 :            : 
    1238         [ +  - ]:         17 :     current_condition = condition_comp( xxi, xet, xze );
    1239         [ -  + ]:         17 :     if( current_condition > condition ) { condition = current_condition; }
    1240                 :            : 
    1241                 :            :     // J(1,1,0):
    1242                 :            : 
    1243 [ +  - ][ +  - ]:         17 :     xxi = node_pos[3] - node_pos[2];
    1244 [ +  - ][ +  - ]:         17 :     xet = node_pos[1] - node_pos[2];
    1245 [ +  - ][ +  - ]:         17 :     xze = node_pos[6] - node_pos[2];
    1246                 :            : 
    1247         [ +  - ]:         17 :     current_condition = condition_comp( xxi, xet, xze );
    1248         [ -  + ]:         17 :     if( current_condition > condition ) { condition = current_condition; }
    1249                 :            : 
    1250                 :            :     // J(0,1,0):
    1251                 :            : 
    1252 [ +  - ][ +  - ]:         17 :     xxi = node_pos[0] - node_pos[3];
    1253 [ +  - ][ +  - ]:         17 :     xet = node_pos[2] - node_pos[3];
    1254 [ +  - ][ +  - ]:         17 :     xze = node_pos[7] - node_pos[3];
    1255                 :            : 
    1256         [ +  - ]:         17 :     current_condition = condition_comp( xxi, xet, xze );
    1257         [ -  + ]:         17 :     if( current_condition > condition ) { condition = current_condition; }
    1258                 :            : 
    1259                 :            :     // J(0,0,1):
    1260                 :            : 
    1261 [ +  - ][ +  - ]:         17 :     xxi = node_pos[7] - node_pos[4];
    1262 [ +  - ][ +  - ]:         17 :     xet = node_pos[5] - node_pos[4];
    1263 [ +  - ][ +  - ]:         17 :     xze = node_pos[0] - node_pos[4];
    1264                 :            : 
    1265         [ +  - ]:         17 :     current_condition = condition_comp( xxi, xet, xze );
    1266         [ -  + ]:         17 :     if( current_condition > condition ) { condition = current_condition; }
    1267                 :            : 
    1268                 :            :     // J(1,0,1):
    1269                 :            : 
    1270 [ +  - ][ +  - ]:         17 :     xxi = node_pos[4] - node_pos[5];
    1271 [ +  - ][ +  - ]:         17 :     xet = node_pos[6] - node_pos[5];
    1272 [ +  - ][ +  - ]:         17 :     xze = node_pos[1] - node_pos[5];
    1273                 :            : 
    1274         [ +  - ]:         17 :     current_condition = condition_comp( xxi, xet, xze );
    1275         [ -  + ]:         17 :     if( current_condition > condition ) { condition = current_condition; }
    1276                 :            : 
    1277                 :            :     // J(1,1,1):
    1278                 :            : 
    1279 [ +  - ][ +  - ]:         17 :     xxi = node_pos[5] - node_pos[6];
    1280 [ +  - ][ +  - ]:         17 :     xet = node_pos[7] - node_pos[6];
    1281 [ +  - ][ +  - ]:         17 :     xze = node_pos[2] - node_pos[6];
    1282                 :            : 
    1283         [ +  - ]:         17 :     current_condition = condition_comp( xxi, xet, xze );
    1284         [ +  + ]:         17 :     if( current_condition > condition ) { condition = current_condition; }
    1285                 :            : 
    1286                 :            :     // J(1,1,1):
    1287                 :            : 
    1288 [ +  - ][ +  - ]:         17 :     xxi = node_pos[6] - node_pos[7];
    1289 [ +  - ][ +  - ]:         17 :     xet = node_pos[4] - node_pos[7];
    1290 [ +  - ][ +  - ]:         17 :     xze = node_pos[3] - node_pos[7];
    1291                 :            : 
    1292         [ +  - ]:         17 :     current_condition = condition_comp( xxi, xet, xze );
    1293         [ -  + ]:         17 :     if( current_condition > condition ) { condition = current_condition; }
    1294                 :            : 
    1295                 :         17 :     condition /= 3.0;
    1296                 :            : 
    1297 [ +  - ][ +  - ]:         17 :     if( condition > 0 ) return (double)VERDICT_MIN( condition, VERDICT_DBL_MAX );
    1298         [ #  # ]:         17 :     return (double)VERDICT_MAX( condition, -VERDICT_DBL_MAX );
    1299                 :            : }
    1300                 :            : 
    1301                 :            : /*!
    1302                 :            :   The maximum Frobenius condition of a hex, a.k.a. condition
    1303                 :            :   NB (P. Pebay 01/25/07):
    1304                 :            :      this method is maintained for backwards compatibility only.
    1305                 :            :      It will become deprecated at some point.
    1306                 :            : 
    1307                 :            : */
    1308                 :          9 : C_FUNC_DEF double v_hex_condition( int /*num_nodes*/, double coordinates[][3] )
    1309                 :            : {
    1310                 :            : 
    1311                 :          9 :     return v_hex_max_aspect_frobenius( 8, coordinates );
    1312                 :            : }
    1313                 :            : 
    1314                 :            : /*!
    1315                 :            :   jacobian of a hex
    1316                 :            : 
    1317                 :            :   Minimum pointwise volume of local map at 8 corners & center of hex
    1318                 :            : */
    1319                 :          9 : C_FUNC_DEF double v_hex_jacobian( int /*num_nodes*/, double coordinates[][3] )
    1320                 :            : {
    1321                 :            : 
    1322 [ +  - ][ +  + ]:         81 :     VerdictVector node_pos[8];
    1323 [ +  - ][ +  + ]:         81 :     make_hex_nodes( coordinates, node_pos );
    1324                 :            : 
    1325                 :          9 :     double jacobian = VERDICT_DBL_MAX;
    1326                 :            :     double current_jacobian;
    1327 [ +  - ][ +  - ]:          9 :     VerdictVector xxi, xet, xze;
                 [ +  - ]
    1328                 :            : 
    1329 [ +  - ][ +  - ]:          9 :     xxi = calc_hex_efg( 1, node_pos );
    1330 [ +  - ][ +  - ]:          9 :     xet = calc_hex_efg( 2, node_pos );
    1331 [ +  - ][ +  - ]:          9 :     xze = calc_hex_efg( 3, node_pos );
    1332                 :            : 
    1333 [ +  - ][ +  - ]:          9 :     current_jacobian = xxi % ( xet * xze ) / 64.0;
    1334         [ +  - ]:          9 :     if( current_jacobian < jacobian ) { jacobian = current_jacobian; }
    1335                 :            : 
    1336                 :            :     // J(0,0,0):
    1337                 :            : 
    1338 [ +  - ][ +  - ]:          9 :     xxi = node_pos[1] - node_pos[0];
    1339 [ +  - ][ +  - ]:          9 :     xet = node_pos[3] - node_pos[0];
    1340 [ +  - ][ +  - ]:          9 :     xze = node_pos[4] - node_pos[0];
    1341                 :            : 
    1342 [ +  - ][ +  - ]:          9 :     current_jacobian = xxi % ( xet * xze );
    1343         [ +  + ]:          9 :     if( current_jacobian < jacobian ) { jacobian = current_jacobian; }
    1344                 :            : 
    1345                 :            :     // J(1,0,0):
    1346                 :            : 
    1347 [ +  - ][ +  - ]:          9 :     xxi = node_pos[2] - node_pos[1];
    1348 [ +  - ][ +  - ]:          9 :     xet = node_pos[0] - node_pos[1];
    1349 [ +  - ][ +  - ]:          9 :     xze = node_pos[5] - node_pos[1];
    1350                 :            : 
    1351 [ +  - ][ +  - ]:          9 :     current_jacobian = xxi % ( xet * xze );
    1352         [ -  + ]:          9 :     if( current_jacobian < jacobian ) { jacobian = current_jacobian; }
    1353                 :            : 
    1354                 :            :     // J(1,1,0):
    1355                 :            : 
    1356 [ +  - ][ +  - ]:          9 :     xxi = node_pos[3] - node_pos[2];
    1357 [ +  - ][ +  - ]:          9 :     xet = node_pos[1] - node_pos[2];
    1358 [ +  - ][ +  - ]:          9 :     xze = node_pos[6] - node_pos[2];
    1359                 :            : 
    1360 [ +  - ][ +  - ]:          9 :     current_jacobian = xxi % ( xet * xze );
    1361         [ -  + ]:          9 :     if( current_jacobian < jacobian ) { jacobian = current_jacobian; }
    1362                 :            : 
    1363                 :            :     // J(0,1,0):
    1364                 :            : 
    1365 [ +  - ][ +  - ]:          9 :     xxi = node_pos[0] - node_pos[3];
    1366 [ +  - ][ +  - ]:          9 :     xet = node_pos[2] - node_pos[3];
    1367 [ +  - ][ +  - ]:          9 :     xze = node_pos[7] - node_pos[3];
    1368                 :            : 
    1369 [ +  - ][ +  - ]:          9 :     current_jacobian = xxi % ( xet * xze );
    1370         [ -  + ]:          9 :     if( current_jacobian < jacobian ) { jacobian = current_jacobian; }
    1371                 :            : 
    1372                 :            :     // J(0,0,1):
    1373                 :            : 
    1374 [ +  - ][ +  - ]:          9 :     xxi = node_pos[7] - node_pos[4];
    1375 [ +  - ][ +  - ]:          9 :     xet = node_pos[5] - node_pos[4];
    1376 [ +  - ][ +  - ]:          9 :     xze = node_pos[0] - node_pos[4];
    1377                 :            : 
    1378 [ +  - ][ +  - ]:          9 :     current_jacobian = xxi % ( xet * xze );
    1379         [ -  + ]:          9 :     if( current_jacobian < jacobian ) { jacobian = current_jacobian; }
    1380                 :            : 
    1381                 :            :     // J(1,0,1):
    1382                 :            : 
    1383 [ +  - ][ +  - ]:          9 :     xxi = node_pos[4] - node_pos[5];
    1384 [ +  - ][ +  - ]:          9 :     xet = node_pos[6] - node_pos[5];
    1385 [ +  - ][ +  - ]:          9 :     xze = node_pos[1] - node_pos[5];
    1386                 :            : 
    1387 [ +  - ][ +  - ]:          9 :     current_jacobian = xxi % ( xet * xze );
    1388         [ -  + ]:          9 :     if( current_jacobian < jacobian ) { jacobian = current_jacobian; }
    1389                 :            : 
    1390                 :            :     // J(1,1,1):
    1391                 :            : 
    1392 [ +  - ][ +  - ]:          9 :     xxi = node_pos[5] - node_pos[6];
    1393 [ +  - ][ +  - ]:          9 :     xet = node_pos[7] - node_pos[6];
    1394 [ +  - ][ +  - ]:          9 :     xze = node_pos[2] - node_pos[6];
    1395                 :            : 
    1396 [ +  - ][ +  - ]:          9 :     current_jacobian = xxi % ( xet * xze );
    1397         [ +  + ]:          9 :     if( current_jacobian < jacobian ) { jacobian = current_jacobian; }
    1398                 :            : 
    1399                 :            :     // J(0,1,1):
    1400                 :            : 
    1401 [ +  - ][ +  - ]:          9 :     xxi = node_pos[6] - node_pos[7];
    1402 [ +  - ][ +  - ]:          9 :     xet = node_pos[4] - node_pos[7];
    1403 [ +  - ][ +  - ]:          9 :     xze = node_pos[3] - node_pos[7];
    1404                 :            : 
    1405 [ +  - ][ +  - ]:          9 :     current_jacobian = xxi % ( xet * xze );
    1406         [ -  + ]:          9 :     if( current_jacobian < jacobian ) { jacobian = current_jacobian; }
    1407                 :            : 
    1408 [ +  - ][ +  - ]:          9 :     if( jacobian > 0 ) return (double)VERDICT_MIN( jacobian, VERDICT_DBL_MAX );
    1409         [ #  # ]:          9 :     return (double)VERDICT_MAX( jacobian, -VERDICT_DBL_MAX );
    1410                 :            : }
    1411                 :            : 
    1412                 :            : /*!
    1413                 :            :   scaled jacobian of a hex
    1414                 :            : 
    1415                 :            :   Minimum Jacobian divided by the lengths of the 3 edge vectors
    1416                 :            : */
    1417                 :          9 : C_FUNC_DEF double v_hex_scaled_jacobian( int /*num_nodes*/, double coordinates[][3] )
    1418                 :            : {
    1419                 :            : 
    1420                 :          9 :     double jacobi, min_norm_jac = VERDICT_DBL_MAX;
    1421                 :            :     // double min_jacobi = VERDICT_DBL_MAX;
    1422                 :            :     double temp_norm_jac, lengths;
    1423                 :            :     double len1_sq, len2_sq, len3_sq;
    1424 [ +  - ][ +  - ]:          9 :     VerdictVector xxi, xet, xze;
                 [ +  - ]
    1425                 :            : 
    1426 [ +  - ][ +  + ]:         81 :     VerdictVector node_pos[8];
    1427 [ +  - ][ +  + ]:         81 :     make_hex_nodes( coordinates, node_pos );
    1428                 :            : 
    1429 [ +  - ][ +  - ]:          9 :     xxi = calc_hex_efg( 1, node_pos );
    1430 [ +  - ][ +  - ]:          9 :     xet = calc_hex_efg( 2, node_pos );
    1431 [ +  - ][ +  - ]:          9 :     xze = calc_hex_efg( 3, node_pos );
    1432                 :            : 
    1433 [ +  - ][ +  - ]:          9 :     jacobi = xxi % ( xet * xze );
    1434                 :            :     // if( jacobi < min_jacobi) { min_jacobi = jacobi; }
    1435                 :            : 
    1436         [ +  - ]:          9 :     len1_sq = xxi.length_squared();
    1437         [ +  - ]:          9 :     len2_sq = xet.length_squared();
    1438         [ +  - ]:          9 :     len3_sq = xze.length_squared();
    1439                 :            : 
    1440 [ +  - ][ +  - ]:          9 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN )
                 [ -  + ]
    1441                 :          0 :         return (double)VERDICT_DBL_MAX;
    1442                 :            : 
    1443                 :          9 :     lengths       = sqrt( len1_sq * len2_sq * len3_sq );
    1444                 :          9 :     temp_norm_jac = jacobi / lengths;
    1445                 :            : 
    1446         [ +  - ]:          9 :     if( temp_norm_jac < min_norm_jac )
    1447                 :          9 :         min_norm_jac = temp_norm_jac;
    1448                 :            :     else
    1449                 :          0 :         temp_norm_jac = jacobi;
    1450                 :            : 
    1451                 :            :     // J(0,0,0):
    1452                 :            : 
    1453 [ +  - ][ +  - ]:          9 :     xxi = node_pos[1] - node_pos[0];
    1454 [ +  - ][ +  - ]:          9 :     xet = node_pos[3] - node_pos[0];
    1455 [ +  - ][ +  - ]:          9 :     xze = node_pos[4] - node_pos[0];
    1456                 :            : 
    1457 [ +  - ][ +  - ]:          9 :     jacobi = xxi % ( xet * xze );
    1458                 :            :     // if( jacobi < min_jacobi ) { min_jacobi = jacobi; }
    1459                 :            : 
    1460         [ +  - ]:          9 :     len1_sq = xxi.length_squared();
    1461         [ +  - ]:          9 :     len2_sq = xet.length_squared();
    1462         [ +  - ]:          9 :     len3_sq = xze.length_squared();
    1463                 :            : 
    1464 [ +  - ][ +  - ]:          9 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN )
                 [ -  + ]
    1465                 :          0 :         return (double)VERDICT_DBL_MAX;
    1466                 :            : 
    1467                 :          9 :     lengths       = sqrt( len1_sq * len2_sq * len3_sq );
    1468                 :          9 :     temp_norm_jac = jacobi / lengths;
    1469         [ +  + ]:          9 :     if( temp_norm_jac < min_norm_jac )
    1470                 :          1 :         min_norm_jac = temp_norm_jac;
    1471                 :            :     else
    1472                 :          8 :         temp_norm_jac = jacobi;
    1473                 :            : 
    1474                 :            :     // J(1,0,0):
    1475                 :            : 
    1476 [ +  - ][ +  - ]:          9 :     xxi = node_pos[2] - node_pos[1];
    1477 [ +  - ][ +  - ]:          9 :     xet = node_pos[0] - node_pos[1];
    1478 [ +  - ][ +  - ]:          9 :     xze = node_pos[5] - node_pos[1];
    1479                 :            : 
    1480 [ +  - ][ +  - ]:          9 :     jacobi = xxi % ( xet * xze );
    1481                 :            :     // if( jacobi < min_jacobi ) { min_jacobi = jacobi; }
    1482                 :            : 
    1483         [ +  - ]:          9 :     len1_sq = xxi.length_squared();
    1484         [ +  - ]:          9 :     len2_sq = xet.length_squared();
    1485         [ +  - ]:          9 :     len3_sq = xze.length_squared();
    1486                 :            : 
    1487 [ +  - ][ +  - ]:          9 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN )
                 [ -  + ]
    1488                 :          0 :         return (double)VERDICT_DBL_MAX;
    1489                 :            : 
    1490                 :          9 :     lengths       = sqrt( len1_sq * len2_sq * len3_sq );
    1491                 :          9 :     temp_norm_jac = jacobi / lengths;
    1492         [ -  + ]:          9 :     if( temp_norm_jac < min_norm_jac )
    1493                 :          0 :         min_norm_jac = temp_norm_jac;
    1494                 :            :     else
    1495                 :          9 :         temp_norm_jac = jacobi;
    1496                 :            : 
    1497                 :            :     // J(1,1,0):
    1498                 :            : 
    1499 [ +  - ][ +  - ]:          9 :     xxi = node_pos[3] - node_pos[2];
    1500 [ +  - ][ +  - ]:          9 :     xet = node_pos[1] - node_pos[2];
    1501 [ +  - ][ +  - ]:          9 :     xze = node_pos[6] - node_pos[2];
    1502                 :            : 
    1503 [ +  - ][ +  - ]:          9 :     jacobi = xxi % ( xet * xze );
    1504                 :            :     // if( jacobi < min_jacobi ) { min_jacobi = jacobi; }
    1505                 :            : 
    1506         [ +  - ]:          9 :     len1_sq = xxi.length_squared();
    1507         [ +  - ]:          9 :     len2_sq = xet.length_squared();
    1508         [ +  - ]:          9 :     len3_sq = xze.length_squared();
    1509                 :            : 
    1510 [ +  - ][ +  - ]:          9 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN )
                 [ -  + ]
    1511                 :          0 :         return (double)VERDICT_DBL_MAX;
    1512                 :            : 
    1513                 :          9 :     lengths       = sqrt( len1_sq * len2_sq * len3_sq );
    1514                 :          9 :     temp_norm_jac = jacobi / lengths;
    1515         [ -  + ]:          9 :     if( temp_norm_jac < min_norm_jac )
    1516                 :          0 :         min_norm_jac = temp_norm_jac;
    1517                 :            :     else
    1518                 :          9 :         temp_norm_jac = jacobi;
    1519                 :            : 
    1520                 :            :     // J(0,1,0):
    1521                 :            : 
    1522 [ +  - ][ +  - ]:          9 :     xxi = node_pos[0] - node_pos[3];
    1523 [ +  - ][ +  - ]:          9 :     xet = node_pos[2] - node_pos[3];
    1524 [ +  - ][ +  - ]:          9 :     xze = node_pos[7] - node_pos[3];
    1525                 :            : 
    1526 [ +  - ][ +  - ]:          9 :     jacobi = xxi % ( xet * xze );
    1527                 :            :     // if( jacobi < min_jacobi ) { min_jacobi = jacobi; }
    1528                 :            : 
    1529         [ +  - ]:          9 :     len1_sq = xxi.length_squared();
    1530         [ +  - ]:          9 :     len2_sq = xet.length_squared();
    1531         [ +  - ]:          9 :     len3_sq = xze.length_squared();
    1532                 :            : 
    1533 [ +  - ][ +  - ]:          9 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN )
                 [ -  + ]
    1534                 :          0 :         return (double)VERDICT_DBL_MAX;
    1535                 :            : 
    1536                 :          9 :     lengths       = sqrt( len1_sq * len2_sq * len3_sq );
    1537                 :          9 :     temp_norm_jac = jacobi / lengths;
    1538         [ -  + ]:          9 :     if( temp_norm_jac < min_norm_jac )
    1539                 :          0 :         min_norm_jac = temp_norm_jac;
    1540                 :            :     else
    1541                 :          9 :         temp_norm_jac = jacobi;
    1542                 :            : 
    1543                 :            :     // J(0,0,1):
    1544                 :            : 
    1545 [ +  - ][ +  - ]:          9 :     xxi = node_pos[7] - node_pos[4];
    1546 [ +  - ][ +  - ]:          9 :     xet = node_pos[5] - node_pos[4];
    1547 [ +  - ][ +  - ]:          9 :     xze = node_pos[0] - node_pos[4];
    1548                 :            : 
    1549 [ +  - ][ +  - ]:          9 :     jacobi = xxi % ( xet * xze );
    1550                 :            :     // if( jacobi < min_jacobi ) { min_jacobi = jacobi; }
    1551                 :            : 
    1552         [ +  - ]:          9 :     len1_sq = xxi.length_squared();
    1553         [ +  - ]:          9 :     len2_sq = xet.length_squared();
    1554         [ +  - ]:          9 :     len3_sq = xze.length_squared();
    1555                 :            : 
    1556 [ +  - ][ +  - ]:          9 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN )
                 [ -  + ]
    1557                 :          0 :         return (double)VERDICT_DBL_MAX;
    1558                 :            : 
    1559                 :          9 :     lengths       = sqrt( len1_sq * len2_sq * len3_sq );
    1560                 :          9 :     temp_norm_jac = jacobi / lengths;
    1561         [ -  + ]:          9 :     if( temp_norm_jac < min_norm_jac )
    1562                 :          0 :         min_norm_jac = temp_norm_jac;
    1563                 :            :     else
    1564                 :          9 :         temp_norm_jac = jacobi;
    1565                 :            : 
    1566                 :            :     // J(1,0,1):
    1567                 :            : 
    1568 [ +  - ][ +  - ]:          9 :     xxi = node_pos[4] - node_pos[5];
    1569 [ +  - ][ +  - ]:          9 :     xet = node_pos[6] - node_pos[5];
    1570 [ +  - ][ +  - ]:          9 :     xze = node_pos[1] - node_pos[5];
    1571                 :            : 
    1572 [ +  - ][ +  - ]:          9 :     jacobi = xxi % ( xet * xze );
    1573                 :            :     // if( jacobi < min_jacobi ) { min_jacobi = jacobi; }
    1574                 :            : 
    1575         [ +  - ]:          9 :     len1_sq = xxi.length_squared();
    1576         [ +  - ]:          9 :     len2_sq = xet.length_squared();
    1577         [ +  - ]:          9 :     len3_sq = xze.length_squared();
    1578                 :            : 
    1579 [ +  - ][ +  - ]:          9 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN )
                 [ -  + ]
    1580                 :          0 :         return (double)VERDICT_DBL_MAX;
    1581                 :            : 
    1582                 :          9 :     lengths       = sqrt( len1_sq * len2_sq * len3_sq );
    1583                 :          9 :     temp_norm_jac = jacobi / lengths;
    1584         [ -  + ]:          9 :     if( temp_norm_jac < min_norm_jac )
    1585                 :          0 :         min_norm_jac = temp_norm_jac;
    1586                 :            :     else
    1587                 :          9 :         temp_norm_jac = jacobi;
    1588                 :            : 
    1589                 :            :     // J(1,1,1):
    1590                 :            : 
    1591 [ +  - ][ +  - ]:          9 :     xxi = node_pos[5] - node_pos[6];
    1592 [ +  - ][ +  - ]:          9 :     xet = node_pos[7] - node_pos[6];
    1593 [ +  - ][ +  - ]:          9 :     xze = node_pos[2] - node_pos[6];
    1594                 :            : 
    1595 [ +  - ][ +  - ]:          9 :     jacobi = xxi % ( xet * xze );
    1596                 :            :     // if( jacobi < min_jacobi ) { min_jacobi = jacobi; }
    1597                 :            : 
    1598         [ +  - ]:          9 :     len1_sq = xxi.length_squared();
    1599         [ +  - ]:          9 :     len2_sq = xet.length_squared();
    1600         [ +  - ]:          9 :     len3_sq = xze.length_squared();
    1601                 :            : 
    1602 [ +  - ][ +  - ]:          9 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN )
                 [ -  + ]
    1603                 :          0 :         return (double)VERDICT_DBL_MAX;
    1604                 :            : 
    1605                 :          9 :     lengths       = sqrt( len1_sq * len2_sq * len3_sq );
    1606                 :          9 :     temp_norm_jac = jacobi / lengths;
    1607         [ +  + ]:          9 :     if( temp_norm_jac < min_norm_jac )
    1608                 :          1 :         min_norm_jac = temp_norm_jac;
    1609                 :            :     else
    1610                 :          8 :         temp_norm_jac = jacobi;
    1611                 :            : 
    1612                 :            :     // J(0,1,1):
    1613                 :            : 
    1614 [ +  - ][ +  - ]:          9 :     xxi = node_pos[6] - node_pos[7];
    1615 [ +  - ][ +  - ]:          9 :     xet = node_pos[4] - node_pos[7];
    1616 [ +  - ][ +  - ]:          9 :     xze = node_pos[3] - node_pos[7];
    1617                 :            : 
    1618 [ +  - ][ +  - ]:          9 :     jacobi = xxi % ( xet * xze );
    1619                 :            :     // if( jacobi < min_jacobi ) { min_jacobi = jacobi; }
    1620                 :            : 
    1621         [ +  - ]:          9 :     len1_sq = xxi.length_squared();
    1622         [ +  - ]:          9 :     len2_sq = xet.length_squared();
    1623         [ +  - ]:          9 :     len3_sq = xze.length_squared();
    1624                 :            : 
    1625 [ +  - ][ +  - ]:          9 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN )
                 [ -  + ]
    1626                 :          0 :         return (double)VERDICT_DBL_MAX;
    1627                 :            : 
    1628                 :          9 :     lengths       = sqrt( len1_sq * len2_sq * len3_sq );
    1629                 :          9 :     temp_norm_jac = jacobi / lengths;
    1630         [ -  + ]:          9 :     if( temp_norm_jac < min_norm_jac ) min_norm_jac = temp_norm_jac;
    1631                 :            :     // else
    1632                 :            :     // temp_norm_jac = jacobi;
    1633                 :            : 
    1634 [ +  - ][ +  - ]:          9 :     if( min_norm_jac > 0 ) return (double)VERDICT_MIN( min_norm_jac, VERDICT_DBL_MAX );
    1635         [ #  # ]:          9 :     return (double)VERDICT_MAX( min_norm_jac, -VERDICT_DBL_MAX );
    1636                 :            : }
    1637                 :            : 
    1638                 :            : /*!
    1639                 :            :   shear of a hex
    1640                 :            : 
    1641                 :            :   3/Condition number of Jacobian Skew matrix
    1642                 :            : */
    1643                 :         18 : C_FUNC_DEF double v_hex_shear( int /*num_nodes*/, double coordinates[][3] )
    1644                 :            : {
    1645                 :            : 
    1646                 :            :     double shear;
    1647                 :         18 :     double min_shear = 1.0;
    1648 [ +  - ][ +  - ]:         18 :     VerdictVector xxi, xet, xze;
                 [ +  - ]
    1649                 :            :     double det, len1_sq, len2_sq, len3_sq, lengths;
    1650                 :            : 
    1651 [ +  - ][ +  + ]:        162 :     VerdictVector node_pos[8];
    1652 [ +  - ][ +  + ]:        162 :     make_hex_nodes( coordinates, node_pos );
    1653                 :            : 
    1654                 :            :     // J(0,0,0):
    1655                 :            : 
    1656 [ +  - ][ +  - ]:         18 :     xxi = node_pos[1] - node_pos[0];
    1657 [ +  - ][ +  - ]:         18 :     xet = node_pos[3] - node_pos[0];
    1658 [ +  - ][ +  - ]:         18 :     xze = node_pos[4] - node_pos[0];
    1659                 :            : 
    1660         [ +  - ]:         18 :     len1_sq = xxi.length_squared();
    1661         [ +  - ]:         18 :     len2_sq = xet.length_squared();
    1662         [ +  - ]:         18 :     len3_sq = xze.length_squared();
    1663                 :            : 
    1664 [ +  - ][ +  - ]:         18 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0;
                 [ -  + ]
    1665                 :            : 
    1666                 :         18 :     lengths = sqrt( len1_sq * len2_sq * len3_sq );
    1667 [ +  - ][ +  - ]:         18 :     det     = xxi % ( xet * xze );
    1668         [ -  + ]:         18 :     if( det < VERDICT_DBL_MIN ) { return 0; }
    1669                 :            : 
    1670                 :         18 :     shear     = det / lengths;
    1671         [ +  + ]:         18 :     min_shear = VERDICT_MIN( shear, min_shear );
    1672                 :            : 
    1673                 :            :     // J(1,0,0):
    1674                 :            : 
    1675 [ +  - ][ +  - ]:         18 :     xxi = node_pos[2] - node_pos[1];
    1676 [ +  - ][ +  - ]:         18 :     xet = node_pos[0] - node_pos[1];
    1677 [ +  - ][ +  - ]:         18 :     xze = node_pos[5] - node_pos[1];
    1678                 :            : 
    1679         [ +  - ]:         18 :     len1_sq = xxi.length_squared();
    1680         [ +  - ]:         18 :     len2_sq = xet.length_squared();
    1681         [ +  - ]:         18 :     len3_sq = xze.length_squared();
    1682                 :            : 
    1683 [ +  - ][ +  - ]:         18 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0;
                 [ -  + ]
    1684                 :            : 
    1685                 :         18 :     lengths = sqrt( len1_sq * len2_sq * len3_sq );
    1686 [ +  - ][ +  - ]:         18 :     det     = xxi % ( xet * xze );
    1687         [ -  + ]:         18 :     if( det < VERDICT_DBL_MIN ) { return 0; }
    1688                 :            : 
    1689                 :         18 :     shear     = det / lengths;
    1690         [ -  + ]:         18 :     min_shear = VERDICT_MIN( shear, min_shear );
    1691                 :            : 
    1692                 :            :     // J(1,1,0):
    1693                 :            : 
    1694 [ +  - ][ +  - ]:         18 :     xxi = node_pos[3] - node_pos[2];
    1695 [ +  - ][ +  - ]:         18 :     xet = node_pos[1] - node_pos[2];
    1696 [ +  - ][ +  - ]:         18 :     xze = node_pos[6] - node_pos[2];
    1697                 :            : 
    1698         [ +  - ]:         18 :     len1_sq = xxi.length_squared();
    1699         [ +  - ]:         18 :     len2_sq = xet.length_squared();
    1700         [ +  - ]:         18 :     len3_sq = xze.length_squared();
    1701                 :            : 
    1702 [ +  - ][ +  - ]:         18 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0;
                 [ -  + ]
    1703                 :            : 
    1704                 :         18 :     lengths = sqrt( len1_sq * len2_sq * len3_sq );
    1705 [ +  - ][ +  - ]:         18 :     det     = xxi % ( xet * xze );
    1706         [ -  + ]:         18 :     if( det < VERDICT_DBL_MIN ) { return 0; }
    1707                 :            : 
    1708                 :         18 :     shear     = det / lengths;
    1709         [ -  + ]:         18 :     min_shear = VERDICT_MIN( shear, min_shear );
    1710                 :            : 
    1711                 :            :     // J(0,1,0):
    1712                 :            : 
    1713 [ +  - ][ +  - ]:         18 :     xxi = node_pos[0] - node_pos[3];
    1714 [ +  - ][ +  - ]:         18 :     xet = node_pos[2] - node_pos[3];
    1715 [ +  - ][ +  - ]:         18 :     xze = node_pos[7] - node_pos[3];
    1716                 :            : 
    1717         [ +  - ]:         18 :     len1_sq = xxi.length_squared();
    1718         [ +  - ]:         18 :     len2_sq = xet.length_squared();
    1719         [ +  - ]:         18 :     len3_sq = xze.length_squared();
    1720                 :            : 
    1721 [ +  - ][ +  - ]:         18 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0;
                 [ -  + ]
    1722                 :            : 
    1723                 :         18 :     lengths = sqrt( len1_sq * len2_sq * len3_sq );
    1724 [ +  - ][ +  - ]:         18 :     det     = xxi % ( xet * xze );
    1725         [ -  + ]:         18 :     if( det < VERDICT_DBL_MIN ) { return 0; }
    1726                 :            : 
    1727                 :         18 :     shear     = det / lengths;
    1728         [ -  + ]:         18 :     min_shear = VERDICT_MIN( shear, min_shear );
    1729                 :            : 
    1730                 :            :     // J(0,0,1):
    1731                 :            : 
    1732 [ +  - ][ +  - ]:         18 :     xxi = node_pos[7] - node_pos[4];
    1733 [ +  - ][ +  - ]:         18 :     xet = node_pos[5] - node_pos[4];
    1734 [ +  - ][ +  - ]:         18 :     xze = node_pos[0] - node_pos[4];
    1735                 :            : 
    1736         [ +  - ]:         18 :     len1_sq = xxi.length_squared();
    1737         [ +  - ]:         18 :     len2_sq = xet.length_squared();
    1738         [ +  - ]:         18 :     len3_sq = xze.length_squared();
    1739                 :            : 
    1740 [ +  - ][ +  - ]:         18 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0;
                 [ -  + ]
    1741                 :            : 
    1742                 :         18 :     lengths = sqrt( len1_sq * len2_sq * len3_sq );
    1743 [ +  - ][ +  - ]:         18 :     det     = xxi % ( xet * xze );
    1744         [ -  + ]:         18 :     if( det < VERDICT_DBL_MIN ) { return 0; }
    1745                 :            : 
    1746                 :         18 :     shear     = det / lengths;
    1747         [ -  + ]:         18 :     min_shear = VERDICT_MIN( shear, min_shear );
    1748                 :            : 
    1749                 :            :     // J(1,0,1):
    1750                 :            : 
    1751 [ +  - ][ +  - ]:         18 :     xxi = node_pos[4] - node_pos[5];
    1752 [ +  - ][ +  - ]:         18 :     xet = node_pos[6] - node_pos[5];
    1753 [ +  - ][ +  - ]:         18 :     xze = node_pos[1] - node_pos[5];
    1754                 :            : 
    1755         [ +  - ]:         18 :     len1_sq = xxi.length_squared();
    1756         [ +  - ]:         18 :     len2_sq = xet.length_squared();
    1757         [ +  - ]:         18 :     len3_sq = xze.length_squared();
    1758                 :            : 
    1759 [ +  - ][ +  - ]:         18 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0;
                 [ -  + ]
    1760                 :            : 
    1761                 :         18 :     lengths = sqrt( len1_sq * len2_sq * len3_sq );
    1762 [ +  - ][ +  - ]:         18 :     det     = xxi % ( xet * xze );
    1763         [ -  + ]:         18 :     if( det < VERDICT_DBL_MIN ) { return 0; }
    1764                 :            : 
    1765                 :         18 :     shear     = det / lengths;
    1766         [ -  + ]:         18 :     min_shear = VERDICT_MIN( shear, min_shear );
    1767                 :            : 
    1768                 :            :     // J(1,1,1):
    1769                 :            : 
    1770 [ +  - ][ +  - ]:         18 :     xxi = node_pos[5] - node_pos[6];
    1771 [ +  - ][ +  - ]:         18 :     xet = node_pos[7] - node_pos[6];
    1772 [ +  - ][ +  - ]:         18 :     xze = node_pos[2] - node_pos[6];
    1773                 :            : 
    1774         [ +  - ]:         18 :     len1_sq = xxi.length_squared();
    1775         [ +  - ]:         18 :     len2_sq = xet.length_squared();
    1776         [ +  - ]:         18 :     len3_sq = xze.length_squared();
    1777                 :            : 
    1778 [ +  - ][ +  - ]:         18 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0;
                 [ -  + ]
    1779                 :            : 
    1780                 :         18 :     lengths = sqrt( len1_sq * len2_sq * len3_sq );
    1781 [ +  - ][ +  - ]:         18 :     det     = xxi % ( xet * xze );
    1782         [ -  + ]:         18 :     if( det < VERDICT_DBL_MIN ) { return 0; }
    1783                 :            : 
    1784                 :         18 :     shear     = det / lengths;
    1785         [ +  + ]:         18 :     min_shear = VERDICT_MIN( shear, min_shear );
    1786                 :            : 
    1787                 :            :     // J(0,1,1):
    1788                 :            : 
    1789 [ +  - ][ +  - ]:         18 :     xxi = node_pos[6] - node_pos[7];
    1790 [ +  - ][ +  - ]:         18 :     xet = node_pos[4] - node_pos[7];
    1791 [ +  - ][ +  - ]:         18 :     xze = node_pos[3] - node_pos[7];
    1792                 :            : 
    1793         [ +  - ]:         18 :     len1_sq = xxi.length_squared();
    1794         [ +  - ]:         18 :     len2_sq = xet.length_squared();
    1795         [ +  - ]:         18 :     len3_sq = xze.length_squared();
    1796                 :            : 
    1797 [ +  - ][ +  - ]:         18 :     if( len1_sq <= VERDICT_DBL_MIN || len2_sq <= VERDICT_DBL_MIN || len3_sq <= VERDICT_DBL_MIN ) return 0;
                 [ -  + ]
    1798                 :            : 
    1799                 :         18 :     lengths = sqrt( len1_sq * len2_sq * len3_sq );
    1800 [ +  - ][ +  - ]:         18 :     det     = xxi % ( xet * xze );
    1801         [ -  + ]:         18 :     if( det < VERDICT_DBL_MIN ) { return 0; }
    1802                 :            : 
    1803                 :         18 :     shear     = det / lengths;
    1804         [ -  + ]:         18 :     min_shear = VERDICT_MIN( shear, min_shear );
    1805                 :            : 
    1806         [ -  + ]:         18 :     if( min_shear <= VERDICT_DBL_MIN ) min_shear = 0;
    1807                 :            : 
    1808 [ +  - ][ +  - ]:         18 :     if( min_shear > 0 ) return (double)VERDICT_MIN( min_shear, VERDICT_DBL_MAX );
    1809         [ #  # ]:         18 :     return (double)VERDICT_MAX( min_shear, -VERDICT_DBL_MAX );
    1810                 :            : }
    1811                 :            : 
    1812                 :            : /*!
    1813                 :            :   shape of a hex
    1814                 :            : 
    1815                 :            :   3/Condition number of weighted Jacobian matrix
    1816                 :            : */
    1817                 :         18 : C_FUNC_DEF double v_hex_shape( int /*num_nodes*/, double coordinates[][3] )
    1818                 :            : {
    1819                 :            : 
    1820                 :            :     double det, shape;
    1821                 :         18 :     double min_shape               = 1.0;
    1822                 :            :     static const double two_thirds = 2.0 / 3.0;
    1823                 :            : 
    1824 [ +  - ][ +  - ]:         18 :     VerdictVector xxi, xet, xze;
                 [ +  - ]
    1825                 :            : 
    1826 [ +  - ][ +  + ]:        162 :     VerdictVector node_pos[8];
    1827 [ +  - ][ +  + ]:        162 :     make_hex_nodes( coordinates, node_pos );
    1828                 :            : 
    1829                 :            :     // J(0,0,0):
    1830                 :            : 
    1831 [ +  - ][ +  - ]:         18 :     xxi = node_pos[1] - node_pos[0];
    1832 [ +  - ][ +  - ]:         18 :     xet = node_pos[3] - node_pos[0];
    1833 [ +  - ][ +  - ]:         18 :     xze = node_pos[4] - node_pos[0];
    1834                 :            : 
    1835 [ +  - ][ +  - ]:         18 :     det = xxi % ( xet * xze );
    1836         [ +  - ]:         18 :     if( det > VERDICT_DBL_MIN )
    1837 [ +  - ][ +  - ]:         18 :         shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze );
                 [ +  - ]
    1838                 :            :     else
    1839                 :          0 :         return 0;
    1840                 :            : 
    1841         [ +  + ]:         18 :     if( shape < min_shape ) { min_shape = shape; }
    1842                 :            : 
    1843                 :            :     // J(1,0,0):
    1844                 :            : 
    1845 [ +  - ][ +  - ]:         18 :     xxi = node_pos[2] - node_pos[1];
    1846 [ +  - ][ +  - ]:         18 :     xet = node_pos[0] - node_pos[1];
    1847 [ +  - ][ +  - ]:         18 :     xze = node_pos[5] - node_pos[1];
    1848                 :            : 
    1849 [ +  - ][ +  - ]:         18 :     det = xxi % ( xet * xze );
    1850         [ +  - ]:         18 :     if( det > VERDICT_DBL_MIN )
    1851 [ +  - ][ +  - ]:         18 :         shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze );
                 [ +  - ]
    1852                 :            :     else
    1853                 :          0 :         return 0;
    1854                 :            : 
    1855         [ -  + ]:         18 :     if( shape < min_shape ) { min_shape = shape; }
    1856                 :            : 
    1857                 :            :     // J(1,1,0):
    1858                 :            : 
    1859 [ +  - ][ +  - ]:         18 :     xxi = node_pos[3] - node_pos[2];
    1860 [ +  - ][ +  - ]:         18 :     xet = node_pos[1] - node_pos[2];
    1861 [ +  - ][ +  - ]:         18 :     xze = node_pos[6] - node_pos[2];
    1862                 :            : 
    1863 [ +  - ][ +  - ]:         18 :     det = xxi % ( xet * xze );
    1864         [ +  - ]:         18 :     if( det > VERDICT_DBL_MIN )
    1865 [ +  - ][ +  - ]:         18 :         shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze );
                 [ +  - ]
    1866                 :            :     else
    1867                 :          0 :         return 0;
    1868                 :            : 
    1869         [ -  + ]:         18 :     if( shape < min_shape ) { min_shape = shape; }
    1870                 :            : 
    1871                 :            :     // J(0,1,0):
    1872                 :            : 
    1873 [ +  - ][ +  - ]:         18 :     xxi = node_pos[0] - node_pos[3];
    1874 [ +  - ][ +  - ]:         18 :     xet = node_pos[2] - node_pos[3];
    1875 [ +  - ][ +  - ]:         18 :     xze = node_pos[7] - node_pos[3];
    1876                 :            : 
    1877 [ +  - ][ +  - ]:         18 :     det = xxi % ( xet * xze );
    1878         [ +  - ]:         18 :     if( det > VERDICT_DBL_MIN )
    1879 [ +  - ][ +  - ]:         18 :         shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze );
                 [ +  - ]
    1880                 :            :     else
    1881                 :          0 :         return 0;
    1882                 :            : 
    1883         [ -  + ]:         18 :     if( shape < min_shape ) { min_shape = shape; }
    1884                 :            : 
    1885                 :            :     // J(0,0,1):
    1886                 :            : 
    1887 [ +  - ][ +  - ]:         18 :     xxi = node_pos[7] - node_pos[4];
    1888 [ +  - ][ +  - ]:         18 :     xet = node_pos[5] - node_pos[4];
    1889 [ +  - ][ +  - ]:         18 :     xze = node_pos[0] - node_pos[4];
    1890                 :            : 
    1891 [ +  - ][ +  - ]:         18 :     det = xxi % ( xet * xze );
    1892         [ +  - ]:         18 :     if( det > VERDICT_DBL_MIN )
    1893 [ +  - ][ +  - ]:         18 :         shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze );
                 [ +  - ]
    1894                 :            :     else
    1895                 :          0 :         return 0;
    1896                 :            : 
    1897         [ -  + ]:         18 :     if( shape < min_shape ) { min_shape = shape; }
    1898                 :            : 
    1899                 :            :     // J(1,0,1):
    1900                 :            : 
    1901 [ +  - ][ +  - ]:         18 :     xxi = node_pos[4] - node_pos[5];
    1902 [ +  - ][ +  - ]:         18 :     xet = node_pos[6] - node_pos[5];
    1903 [ +  - ][ +  - ]:         18 :     xze = node_pos[1] - node_pos[5];
    1904                 :            : 
    1905 [ +  - ][ +  - ]:         18 :     det = xxi % ( xet * xze );
    1906         [ +  - ]:         18 :     if( det > VERDICT_DBL_MIN )
    1907 [ +  - ][ +  - ]:         18 :         shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze );
                 [ +  - ]
    1908                 :            :     else
    1909                 :          0 :         return 0;
    1910                 :            : 
    1911         [ -  + ]:         18 :     if( shape < min_shape ) { min_shape = shape; }
    1912                 :            : 
    1913                 :            :     // J(1,1,1):
    1914                 :            : 
    1915 [ +  - ][ +  - ]:         18 :     xxi = node_pos[5] - node_pos[6];
    1916 [ +  - ][ +  - ]:         18 :     xet = node_pos[7] - node_pos[6];
    1917 [ +  - ][ +  - ]:         18 :     xze = node_pos[2] - node_pos[6];
    1918                 :            : 
    1919 [ +  - ][ +  - ]:         18 :     det = xxi % ( xet * xze );
    1920         [ +  - ]:         18 :     if( det > VERDICT_DBL_MIN )
    1921 [ +  - ][ +  - ]:         18 :         shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze );
                 [ +  - ]
    1922                 :            :     else
    1923                 :          0 :         return 0;
    1924                 :            : 
    1925         [ -  + ]:         18 :     if( shape < min_shape ) { min_shape = shape; }
    1926                 :            : 
    1927                 :            :     // J(1,1,1):
    1928                 :            : 
    1929 [ +  - ][ +  - ]:         18 :     xxi = node_pos[6] - node_pos[7];
    1930 [ +  - ][ +  - ]:         18 :     xet = node_pos[4] - node_pos[7];
    1931 [ +  - ][ +  - ]:         18 :     xze = node_pos[3] - node_pos[7];
    1932                 :            : 
    1933 [ +  - ][ +  - ]:         18 :     det = xxi % ( xet * xze );
    1934         [ +  - ]:         18 :     if( det > VERDICT_DBL_MIN )
    1935 [ +  - ][ +  - ]:         18 :         shape = 3 * pow( det, two_thirds ) / ( xxi % xxi + xet % xet + xze % xze );
                 [ +  - ]
    1936                 :            :     else
    1937                 :          0 :         return 0;
    1938                 :            : 
    1939         [ -  + ]:         18 :     if( shape < min_shape ) { min_shape = shape; }
    1940                 :            : 
    1941         [ -  + ]:         18 :     if( min_shape <= VERDICT_DBL_MIN ) min_shape = 0;
    1942                 :            : 
    1943 [ +  - ][ +  - ]:         18 :     if( min_shape > 0 ) return (double)VERDICT_MIN( min_shape, VERDICT_DBL_MAX );
    1944         [ #  # ]:         18 :     return (double)VERDICT_MAX( min_shape, -VERDICT_DBL_MAX );
    1945                 :            : }
    1946                 :            : 
    1947                 :            : /*!
    1948                 :            :   relative size of a hex
    1949                 :            : 
    1950                 :            :   Min( J, 1/J ), where J is determinant of weighted Jacobian matrix
    1951                 :            : */
    1952                 :         27 : C_FUNC_DEF double v_hex_relative_size_squared( int /*num_nodes*/, double coordinates[][3] )
    1953                 :            : {
    1954                 :         27 :     double size = 0;
    1955                 :            :     double tau;
    1956                 :            : 
    1957 [ +  - ][ +  - ]:         27 :     VerdictVector xxi, xet, xze;
                 [ +  - ]
    1958                 :         27 :     double det, det_sum = 0;
    1959                 :            : 
    1960         [ +  - ]:         27 :     v_hex_get_weight( xxi, xet, xze );
    1961                 :            : 
    1962                 :            :     // This is the average relative size
    1963 [ +  - ][ +  - ]:         27 :     double detw = xxi % ( xet * xze );
    1964                 :            : 
    1965         [ -  + ]:         27 :     if( detw < VERDICT_DBL_MIN ) return 0;
    1966                 :            : 
    1967 [ +  - ][ +  + ]:        243 :     VerdictVector node_pos[8];
    1968 [ +  - ][ +  + ]:        243 :     make_hex_nodes( coordinates, node_pos );
    1969                 :            : 
    1970                 :            :     // J(0,0,0):
    1971                 :            : 
    1972 [ +  - ][ +  - ]:         27 :     xxi = node_pos[1] - node_pos[0];
    1973 [ +  - ][ +  - ]:         27 :     xet = node_pos[3] - node_pos[0];
    1974 [ +  - ][ +  - ]:         27 :     xze = node_pos[4] - node_pos[0];
    1975                 :            : 
    1976 [ +  - ][ +  - ]:         27 :     det = xxi % ( xet * xze );
    1977                 :         27 :     det_sum += det;
    1978                 :            : 
    1979                 :            :     // J(1,0,0):
    1980                 :            : 
    1981 [ +  - ][ +  - ]:         27 :     xxi = node_pos[2] - node_pos[1];
    1982 [ +  - ][ +  - ]:         27 :     xet = node_pos[0] - node_pos[1];
    1983 [ +  - ][ +  - ]:         27 :     xze = node_pos[5] - node_pos[1];
    1984                 :            : 
    1985 [ +  - ][ +  - ]:         27 :     det = xxi % ( xet * xze );
    1986                 :         27 :     det_sum += det;
    1987                 :            : 
    1988                 :            :     // J(0,1,0):
    1989                 :            : 
    1990 [ +  - ][ +  - ]:         27 :     xxi = node_pos[3] - node_pos[2];
    1991 [ +  - ][ +  - ]:         27 :     xet = node_pos[1] - node_pos[2];
    1992 [ +  - ][ +  - ]:         27 :     xze = node_pos[6] - node_pos[2];
    1993                 :            : 
    1994 [ +  - ][ +  - ]:         27 :     det = xxi % ( xet * xze );
    1995                 :         27 :     det_sum += det;
    1996                 :            : 
    1997                 :            :     // J(1,1,0):
    1998                 :            : 
    1999 [ +  - ][ +  - ]:         27 :     xxi = node_pos[0] - node_pos[3];
    2000 [ +  - ][ +  - ]:         27 :     xet = node_pos[2] - node_pos[3];
    2001 [ +  - ][ +  - ]:         27 :     xze = node_pos[7] - node_pos[3];
    2002                 :            : 
    2003 [ +  - ][ +  - ]:         27 :     det = xxi % ( xet * xze );
    2004                 :         27 :     det_sum += det;
    2005                 :            : 
    2006                 :            :     // J(0,1,0):
    2007                 :            : 
    2008 [ +  - ][ +  - ]:         27 :     xxi = node_pos[7] - node_pos[4];
    2009 [ +  - ][ +  - ]:         27 :     xet = node_pos[5] - node_pos[4];
    2010 [ +  - ][ +  - ]:         27 :     xze = node_pos[0] - node_pos[4];
    2011                 :            : 
    2012 [ +  - ][ +  - ]:         27 :     det = xxi % ( xet * xze );
    2013                 :         27 :     det_sum += det;
    2014                 :            : 
    2015                 :            :     // J(1,0,1):
    2016                 :            : 
    2017 [ +  - ][ +  - ]:         27 :     xxi = node_pos[4] - node_pos[5];
    2018 [ +  - ][ +  - ]:         27 :     xet = node_pos[6] - node_pos[5];
    2019 [ +  - ][ +  - ]:         27 :     xze = node_pos[1] - node_pos[5];
    2020                 :            : 
    2021 [ +  - ][ +  - ]:         27 :     det = xxi % ( xet * xze );
    2022                 :         27 :     det_sum += det;
    2023                 :            : 
    2024                 :            :     // J(1,1,1):
    2025                 :            : 
    2026 [ +  - ][ +  - ]:         27 :     xxi = node_pos[5] - node_pos[6];
    2027 [ +  - ][ +  - ]:         27 :     xet = node_pos[7] - node_pos[6];
    2028 [ +  - ][ +  - ]:         27 :     xze = node_pos[2] - node_pos[6];
    2029                 :            : 
    2030 [ +  - ][ +  - ]:         27 :     det = xxi % ( xet * xze );
    2031                 :         27 :     det_sum += det;
    2032                 :            : 
    2033                 :            :     // J(1,1,1):
    2034                 :            : 
    2035 [ +  - ][ +  - ]:         27 :     xxi = node_pos[6] - node_pos[7];
    2036 [ +  - ][ +  - ]:         27 :     xet = node_pos[4] - node_pos[7];
    2037 [ +  - ][ +  - ]:         27 :     xze = node_pos[3] - node_pos[7];
    2038                 :            : 
    2039 [ +  - ][ +  - ]:         27 :     det = xxi % ( xet * xze );
    2040                 :         27 :     det_sum += det;
    2041                 :            : 
    2042         [ +  - ]:         27 :     if( det_sum > VERDICT_DBL_MIN )
    2043                 :            :     {
    2044                 :         27 :         tau = det_sum / ( 8 * detw );
    2045                 :            : 
    2046         [ +  - ]:         27 :         tau = VERDICT_MIN( tau, 1.0 / tau );
    2047                 :            : 
    2048                 :         27 :         size = tau * tau;
    2049                 :            :     }
    2050                 :            : 
    2051 [ +  - ][ +  - ]:         27 :     if( size > 0 ) return (double)VERDICT_MIN( size, VERDICT_DBL_MAX );
    2052         [ #  # ]:         27 :     return (double)VERDICT_MAX( size, -VERDICT_DBL_MAX );
    2053                 :            : }
    2054                 :            : 
    2055                 :            : /*!
    2056                 :            :   shape and size of a hex
    2057                 :            : 
    2058                 :            :   Product of Shape and Relative Size
    2059                 :            : */
    2060                 :          9 : C_FUNC_DEF double v_hex_shape_and_size( int num_nodes, double coordinates[][3] )
    2061                 :            : {
    2062                 :          9 :     double size  = v_hex_relative_size_squared( num_nodes, coordinates );
    2063                 :          9 :     double shape = v_hex_shape( num_nodes, coordinates );
    2064                 :            : 
    2065                 :          9 :     double shape_size = size * shape;
    2066                 :            : 
    2067 [ +  - ][ +  - ]:          9 :     if( shape_size > 0 ) return (double)VERDICT_MIN( shape_size, VERDICT_DBL_MAX );
    2068         [ #  # ]:          0 :     return (double)VERDICT_MAX( shape_size, -VERDICT_DBL_MAX );
    2069                 :            : }
    2070                 :            : 
    2071                 :            : /*!
    2072                 :            :   shear and size of a hex
    2073                 :            : 
    2074                 :            :   Product of Shear and Relative Size
    2075                 :            : */
    2076                 :          9 : C_FUNC_DEF double v_hex_shear_and_size( int num_nodes, double coordinates[][3] )
    2077                 :            : {
    2078                 :          9 :     double size  = v_hex_relative_size_squared( num_nodes, coordinates );
    2079                 :          9 :     double shear = v_hex_shear( num_nodes, coordinates );
    2080                 :            : 
    2081                 :          9 :     double shear_size = shear * size;
    2082                 :            : 
    2083 [ +  - ][ +  - ]:          9 :     if( shear_size > 0 ) return (double)VERDICT_MIN( shear_size, VERDICT_DBL_MAX );
    2084         [ #  # ]:          0 :     return (double)VERDICT_MAX( shear_size, -VERDICT_DBL_MAX );
    2085                 :            : }
    2086                 :            : 
    2087                 :            : /*!
    2088                 :            :   distortion of a hex
    2089                 :            : */
    2090                 :         17 : C_FUNC_DEF double v_hex_distortion( int num_nodes, double coordinates[][3] )
    2091                 :            : {
    2092                 :            : 
    2093                 :            :     // use 2x2 gauss points for linear hex and 3x3 for 2nd order hex
    2094                 :         17 :     int number_of_gauss_points = 0;
    2095         [ +  - ]:         17 :     if( num_nodes == 8 )
    2096                 :            :         // 2x2 quadrature rule
    2097                 :         17 :         number_of_gauss_points = 2;
    2098         [ #  # ]:          0 :     else if( num_nodes == 20 )
    2099                 :            :         // 3x3 quadrature rule
    2100                 :          0 :         number_of_gauss_points = 3;
    2101                 :            : 
    2102                 :         17 :     int number_dimension             = 3;
    2103                 :         17 :     int total_number_of_gauss_points = number_of_gauss_points * number_of_gauss_points * number_of_gauss_points;
    2104                 :         17 :     double distortion                = VERDICT_DBL_MAX;
    2105                 :            : 
    2106                 :            :     // maxTotalNumberGaussPoints =27, maxNumberNodes = 20
    2107                 :            :     // they are defined in GaussIntegration.hpp
    2108                 :            :     // This is used to make these arrays static.
    2109                 :            :     // I tried dynamically allocated arrays but the new and delete
    2110                 :            :     // was very expensive
    2111                 :            : 
    2112                 :            :     double shape_function[maxTotalNumberGaussPoints][maxNumberNodes];
    2113                 :            :     double dndy1[maxTotalNumberGaussPoints][maxNumberNodes];
    2114                 :            :     double dndy2[maxTotalNumberGaussPoints][maxNumberNodes];
    2115                 :            :     double dndy3[maxTotalNumberGaussPoints][maxNumberNodes];
    2116                 :            :     double weight[maxTotalNumberGaussPoints];
    2117                 :            : 
    2118                 :            :     // create an object of GaussIntegration
    2119         [ +  - ]:         17 :     GaussIntegration::initialize( number_of_gauss_points, num_nodes, number_dimension );
    2120         [ +  - ]:         17 :     GaussIntegration::calculate_shape_function_3d_hex();
    2121         [ +  - ]:         17 :     GaussIntegration::get_shape_func( shape_function[0], dndy1[0], dndy2[0], dndy3[0], weight );
    2122                 :            : 
    2123 [ +  - ][ +  - ]:         17 :     VerdictVector xxi, xet, xze, xin;
         [ +  - ][ +  - ]
    2124                 :            : 
    2125                 :            :     double jacobian, minimum_jacobian;
    2126                 :         17 :     double element_volume = 0.0;
    2127                 :         17 :     minimum_jacobian      = VERDICT_DBL_MAX;
    2128                 :            :     // calculate element volume
    2129                 :            :     int ife, ja;
    2130         [ +  + ]:        153 :     for( ife = 0; ife < total_number_of_gauss_points; ife++ )
    2131                 :            :     {
    2132                 :            : 
    2133         [ +  - ]:        136 :         xxi.set( 0.0, 0.0, 0.0 );
    2134         [ +  - ]:        136 :         xet.set( 0.0, 0.0, 0.0 );
    2135         [ +  - ]:        136 :         xze.set( 0.0, 0.0, 0.0 );
    2136                 :            : 
    2137         [ +  + ]:       1224 :         for( ja = 0; ja < num_nodes; ja++ )
    2138                 :            :         {
    2139         [ +  - ]:       1088 :             xin.set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] );
    2140 [ +  - ][ +  - ]:       1088 :             xxi += dndy1[ife][ja] * xin;
    2141 [ +  - ][ +  - ]:       1088 :             xet += dndy2[ife][ja] * xin;
    2142 [ +  - ][ +  - ]:       1088 :             xze += dndy3[ife][ja] * xin;
    2143                 :            :         }
    2144                 :            : 
    2145 [ +  - ][ +  - ]:        136 :         jacobian = xxi % ( xet * xze );
    2146         [ +  + ]:        136 :         if( minimum_jacobian > jacobian ) minimum_jacobian = jacobian;
    2147                 :            : 
    2148                 :        136 :         element_volume += weight[ife] * jacobian;
    2149                 :            :     }
    2150                 :            : 
    2151                 :            :     // loop through all nodes
    2152                 :            :     double dndy1_at_node[maxNumberNodes][maxNumberNodes];
    2153                 :            :     double dndy2_at_node[maxNumberNodes][maxNumberNodes];
    2154                 :            :     double dndy3_at_node[maxNumberNodes][maxNumberNodes];
    2155                 :            : 
    2156         [ +  - ]:         17 :     GaussIntegration::calculate_derivative_at_nodes_3d( dndy1_at_node, dndy2_at_node, dndy3_at_node );
    2157                 :            :     int node_id;
    2158         [ +  + ]:        153 :     for( node_id = 0; node_id < num_nodes; node_id++ )
    2159                 :            :     {
    2160                 :            : 
    2161         [ +  - ]:        136 :         xxi.set( 0.0, 0.0, 0.0 );
    2162         [ +  - ]:        136 :         xet.set( 0.0, 0.0, 0.0 );
    2163         [ +  - ]:        136 :         xze.set( 0.0, 0.0, 0.0 );
    2164                 :            : 
    2165         [ +  + ]:       1224 :         for( ja = 0; ja < num_nodes; ja++ )
    2166                 :            :         {
    2167         [ +  - ]:       1088 :             xin.set( coordinates[ja][0], coordinates[ja][1], coordinates[ja][2] );
    2168 [ +  - ][ +  - ]:       1088 :             xxi += dndy1_at_node[node_id][ja] * xin;
    2169 [ +  - ][ +  - ]:       1088 :             xet += dndy2_at_node[node_id][ja] * xin;
    2170 [ +  - ][ +  - ]:       1088 :             xze += dndy3_at_node[node_id][ja] * xin;
    2171                 :            :         }
    2172                 :            : 
    2173 [ +  - ][ +  - ]:        136 :         jacobian = xxi % ( xet * xze );
    2174         [ +  + ]:        136 :         if( minimum_jacobian > jacobian ) minimum_jacobian = jacobian;
    2175                 :            :     }
    2176                 :         17 :     distortion = minimum_jacobian / element_volume * 8.;
    2177                 :         17 :     return (double)distortion;
    2178                 :            : }
    2179                 :            : 
    2180                 :            : /*
    2181                 :            : C_FUNC_DEF double hex_jac_normjac_oddy_cond( int choices[],
    2182                 :            :                       double coordinates[][3],
    2183                 :            :                       double answers[4]  )
    2184                 :            : {
    2185                 :            : 
    2186                 :            :   //Define variables
    2187                 :            :   int i;
    2188                 :            : 
    2189                 :            :   double xxi[3], xet[3], xze[3];
    2190                 :            :   double norm_jacobian = 0.0, current_norm_jac = 0.0;
    2191                 :            :         double jacobian = 0.0, current_jacobian = 0.0;
    2192                 :            :   double oddy = 0.0, current_oddy = 0.0;
    2193                 :            :   double condition = 0.0, current_condition = 0.0;
    2194                 :            : 
    2195                 :            : 
    2196                 :            :         for( i=0; i<3; i++)
    2197                 :            :           xxi[i] = calc_hex_efg( 2, i, coordinates );
    2198                 :            :         for( i=0; i<3; i++)
    2199                 :            :           xet[i] = calc_hex_efg( 3, i, coordinates );
    2200                 :            :         for( i=0; i<3; i++)
    2201                 :            :           xze[i] = calc_hex_efg( 6, i, coordinates );
    2202                 :            : 
    2203                 :            :   // norm jacobian and jacobian
    2204                 :            :   if( choices[0] || choices[1] )
    2205                 :            :   {
    2206                 :            :     current_jacobian = determinant( xxi, xet, xze  );
    2207                 :            :     current_norm_jac = normalize_jacobian( current_jacobian,
    2208                 :            :             xxi, xet, xze );
    2209                 :            : 
    2210                 :            :     if (current_norm_jac < norm_jacobian) { norm_jacobian = current_norm_jac; }
    2211                 :            : 
    2212                 :            :     current_jacobian /= 64.0;
    2213                 :            :     if (current_jacobian < jacobian) { jacobian = current_jacobian; }
    2214                 :            :   }
    2215                 :            : 
    2216                 :            :   // oddy
    2217                 :            :   if( choices[2] )
    2218                 :            :   {
    2219                 :            :     current_oddy = oddy_comp( xxi, xet, xze );
    2220                 :            :       if ( current_oddy > oddy ) { oddy = current_oddy; }
    2221                 :            :   }
    2222                 :            : 
    2223                 :            :   // condition
    2224                 :            :   if( choices[3] )
    2225                 :            :   {
    2226                 :            :     current_condition = condition_comp( xxi, xet, xze );
    2227                 :            :     if ( current_condition > condition ) { condition = current_condition; }
    2228                 :            :   }
    2229                 :            : 
    2230                 :            : 
    2231                 :            :   for( i=0; i<3; i++)
    2232                 :            :   {
    2233                 :            :     xxi[i] = coordinates[1][i] - coordinates[0][i];
    2234                 :            :     xet[i] = coordinates[3][i] - coordinates[0][i];
    2235                 :            :     xze[i] = coordinates[4][i] - coordinates[0][i];
    2236                 :            :   }
    2237                 :            : 
    2238                 :            :   // norm jacobian and jacobian
    2239                 :            :   if( choices[0] || choices[1] )
    2240                 :            :   {
    2241                 :            :     current_jacobian = determinant( xxi, xet, xze  );
    2242                 :            :     current_norm_jac = normalize_jacobian( current_jacobian,
    2243                 :            :             xxi, xet, xze );
    2244                 :            : 
    2245                 :            :     if (current_norm_jac < norm_jacobian) { norm_jacobian = current_norm_jac; }
    2246                 :            :     if (current_jacobian < jacobian) { jacobian = current_jacobian; }
    2247                 :            :   }
    2248                 :            : 
    2249                 :            :   // oddy
    2250                 :            :   if( choices[2] )
    2251                 :            :   {
    2252                 :            :     current_oddy = oddy_comp( xxi, xet, xze );
    2253                 :            :       if ( current_oddy > oddy ) { oddy = current_oddy; }
    2254                 :            :   }
    2255                 :            : 
    2256                 :            :   // condition
    2257                 :            :   if( choices[3] )
    2258                 :            :   {
    2259                 :            :     current_condition = condition_comp( xxi, xet, xze );
    2260                 :            :     if ( current_condition > condition ) { condition = current_condition; }
    2261                 :            :   }
    2262                 :            : 
    2263                 :            : 
    2264                 :            :   for( i=0; i<3; i++)
    2265                 :            :   {
    2266                 :            :           xxi[i] = coordinates[1][i] - coordinates[0][i];
    2267                 :            :           xet[i] = coordinates[2][i] - coordinates[1][i];
    2268                 :            :           xze[i] = coordinates[5][i] - coordinates[1][i];
    2269                 :            :   }
    2270                 :            : 
    2271                 :            :   // norm jacobian and jacobian
    2272                 :            :   if( choices[0] || choices[1] )
    2273                 :            :   {
    2274                 :            :     current_jacobian = determinant( xxi,  xet, xze );
    2275                 :            :     current_norm_jac = normalize_jacobian( current_jacobian,
    2276                 :            :             xxi, xet, xze );
    2277                 :            : 
    2278                 :            :     if (current_norm_jac < norm_jacobian) { norm_jacobian = current_norm_jac; }
    2279                 :            :     if (current_jacobian < jacobian) { jacobian = current_jacobian; }
    2280                 :            :   }
    2281                 :            : 
    2282                 :            :   // oddy
    2283                 :            :   if( choices[2] )
    2284                 :            :   {
    2285                 :            :     current_oddy = oddy_comp( xxi, xet, xze );
    2286                 :            :       if ( current_oddy > oddy ) { oddy = current_oddy; }
    2287                 :            :   }
    2288                 :            : 
    2289                 :            :   // condition
    2290                 :            :   if( choices[3] )
    2291                 :            :   {
    2292                 :            :     current_condition = condition_comp( xxi, xet, xze );
    2293                 :            :     if ( current_condition > condition ) { condition = current_condition; }
    2294                 :            :   }
    2295                 :            : 
    2296                 :            : 
    2297                 :            :   for( i=0; i<3; i++)
    2298                 :            :   {
    2299                 :            :           xxi[i] = coordinates[2][i] - coordinates[3][i];
    2300                 :            :           xet[i] = coordinates[3][i] - coordinates[0][i];
    2301                 :            :           xze[i] = coordinates[7][i] - coordinates[3][i];
    2302                 :            :   }
    2303                 :            : 
    2304                 :            :   // norm jacobian and jacobian
    2305                 :            :   if( choices[0] || choices[1] )
    2306                 :            :   {
    2307                 :            :     current_jacobian = determinant( xxi, xet, xze );
    2308                 :            :     current_norm_jac = normalize_jacobian( current_jacobian,
    2309                 :            :             xxi, xet, xze );
    2310                 :            : 
    2311                 :            :     if (current_norm_jac < norm_jacobian) { norm_jacobian = current_norm_jac; }
    2312                 :            :     if (current_jacobian < jacobian) { jacobian = current_jacobian; }
    2313                 :            :   }
    2314                 :            : 
    2315                 :            :   // oddy
    2316                 :            :   if( choices[2] )
    2317                 :            :   {
    2318                 :            :     current_oddy = oddy_comp( xxi, xet, xze );
    2319                 :            :       if ( current_oddy > oddy ) { oddy = current_oddy; }
    2320                 :            :   }
    2321                 :            : 
    2322                 :            :   // condition
    2323                 :            :   if( choices[3] )
    2324                 :            :   {
    2325                 :            :     current_condition = condition_comp( xxi, xet, xze );
    2326                 :            :     if ( current_condition > condition ) { condition = current_condition; }
    2327                 :            :   }
    2328                 :            : 
    2329                 :            : 
    2330                 :            :   for( i=0; i<3; i++)
    2331                 :            :   {
    2332                 :            :           xxi[i] = coordinates[5][i] - coordinates[4][i];
    2333                 :            :           xet[i] = coordinates[7][i] - coordinates[4][i];
    2334                 :            :           xze[i] = coordinates[4][i] - coordinates[0][i];
    2335                 :            :   }
    2336                 :            : 
    2337                 :            : 
    2338                 :            :   // norm jacobian and jacobian
    2339                 :            :   if( choices[0] || choices[1] )
    2340                 :            :   {
    2341                 :            :     current_jacobian = determinant( xxi, xet, xze );
    2342                 :            :     current_norm_jac = normalize_jacobian( current_jacobian,
    2343                 :            :             xxi, xet, xze );
    2344                 :            : 
    2345                 :            :     if (current_norm_jac < norm_jacobian) { norm_jacobian = current_norm_jac; }
    2346                 :            :     if (current_jacobian < jacobian) { jacobian = current_jacobian; }
    2347                 :            :   }
    2348                 :            : 
    2349                 :            :   // oddy
    2350                 :            :   if( choices[2] )
    2351                 :            :   {
    2352                 :            :     current_oddy = oddy_comp( xxi, xet, xze );
    2353                 :            :       if ( current_oddy > oddy ) { oddy = current_oddy; }
    2354                 :            :   }
    2355                 :            : 
    2356                 :            :   // condition
    2357                 :            :   if( choices[3] )
    2358                 :            :   {
    2359                 :            :     current_condition = condition_comp( xxi, xet, xze );
    2360                 :            :     if ( current_condition > condition ) { condition = current_condition; }
    2361                 :            :   }
    2362                 :            : 
    2363                 :            : 
    2364                 :            :   for( i=0; i<3; i++)
    2365                 :            :   {
    2366                 :            :           xxi[i] = coordinates[2][i] - coordinates[3][i];
    2367                 :            :           xet[i] = coordinates[2][i] - coordinates[1][i];
    2368                 :            :           xze[i] = coordinates[6][i] - coordinates[2][i];
    2369                 :            :   }
    2370                 :            : 
    2371                 :            :   // norm jacobian and jacobian
    2372                 :            :   if( choices[0] || choices[1] )
    2373                 :            :   {
    2374                 :            :     current_jacobian = determinant( xxi, xet, xze );
    2375                 :            :     current_norm_jac = normalize_jacobian( current_jacobian,
    2376                 :            :             xxi, xet, xze );
    2377                 :            : 
    2378                 :            :     if (current_norm_jac < norm_jacobian) { norm_jacobian = current_norm_jac; }
    2379                 :            :     if (current_jacobian < jacobian) { jacobian = current_jacobian; }
    2380                 :            :   }
    2381                 :            : 
    2382                 :            :   // oddy
    2383                 :            :   if( choices[2] )
    2384                 :            :   {
    2385                 :            :     current_oddy = oddy_comp( xxi, xet, xze );
    2386                 :            :       if ( current_oddy > oddy ) { oddy = current_oddy; }
    2387                 :            :   }
    2388                 :            : 
    2389                 :            :   // condition
    2390                 :            :   if( choices[3] )
    2391                 :            :   {
    2392                 :            :     current_condition = condition_comp( xxi, xet, xze );
    2393                 :            :     if ( current_condition > condition ) { condition = current_condition; }
    2394                 :            :   }
    2395                 :            : 
    2396                 :            : 
    2397                 :            :   for( i=0; i<3; i++)
    2398                 :            :   {
    2399                 :            :           xxi[i] = coordinates[5][i] - coordinates[4][i];
    2400                 :            :           xet[i] = coordinates[6][i] - coordinates[5][i];
    2401                 :            :           xze[i] = coordinates[5][i] - coordinates[1][i];
    2402                 :            :   }
    2403                 :            : 
    2404                 :            : 
    2405                 :            :   // norm jacobian and jacobian
    2406                 :            :   if( choices[0] || choices[1] )
    2407                 :            :   {
    2408                 :            :     current_jacobian = determinant( xxi, xet, xze );
    2409                 :            :     current_norm_jac = normalize_jacobian( current_jacobian,
    2410                 :            :             xxi, xet, xze );
    2411                 :            : 
    2412                 :            :     if (current_norm_jac < norm_jacobian) { norm_jacobian = current_norm_jac; }
    2413                 :            :     if (current_jacobian < jacobian) { jacobian = current_jacobian; }
    2414                 :            :   }
    2415                 :            : 
    2416                 :            :   // oddy
    2417                 :            :   if( choices[2] )
    2418                 :            :   {
    2419                 :            :     current_oddy = oddy_comp( xxi, xet, xze );
    2420                 :            :       if ( current_oddy > oddy ) { oddy = current_oddy; }
    2421                 :            :   }
    2422                 :            : 
    2423                 :            :   // condition
    2424                 :            :   if( choices[3] )
    2425                 :            :   {
    2426                 :            :     current_condition = condition_comp( xxi, xet, xze );
    2427                 :            :     if ( current_condition > condition ) { condition = current_condition; }
    2428                 :            :   }
    2429                 :            : 
    2430                 :            : 
    2431                 :            :   for( i=0; i<3; i++)
    2432                 :            :   {
    2433                 :            :           xxi[i] = coordinates[6][i] - coordinates[7][i];
    2434                 :            :           xet[i] = coordinates[7][i] - coordinates[4][i];
    2435                 :            :           xze[i] = coordinates[7][i] - coordinates[3][i];
    2436                 :            :   }
    2437                 :            : 
    2438                 :            : 
    2439                 :            :   // norm jacobian and jacobian
    2440                 :            :   if( choices[0] || choices[1] )
    2441                 :            :   {
    2442                 :            :     current_jacobian = determinant( xxi, xet, xze );
    2443                 :            :     current_norm_jac = normalize_jacobian( current_jacobian,
    2444                 :            :             xxi, xet, xze );
    2445                 :            : 
    2446                 :            :     if (current_norm_jac < norm_jacobian) { norm_jacobian = current_norm_jac; }
    2447                 :            :     if (current_jacobian < jacobian) { jacobian = current_jacobian; }
    2448                 :            :   }
    2449                 :            : 
    2450                 :            :   // oddy
    2451                 :            :   if( choices[2] )
    2452                 :            :   {
    2453                 :            :     current_oddy = oddy_comp( xxi, xet, xze );
    2454                 :            :       if ( current_oddy > oddy ) { oddy = current_oddy; }
    2455                 :            :   }
    2456                 :            : 
    2457                 :            :   // condition
    2458                 :            :   if( choices[3] )
    2459                 :            :   {
    2460                 :            :     current_condition = condition_comp( xxi, xet, xze );
    2461                 :            :     if ( current_condition > condition ) { condition = current_condition; }
    2462                 :            :   }
    2463                 :            : 
    2464                 :            : 
    2465                 :            :   for( i=0; i<3; i++)
    2466                 :            :   {
    2467                 :            :           xxi[i] = coordinates[6][i] - coordinates[7][i];
    2468                 :            :           xet[i] = coordinates[6][i] - coordinates[5][i];
    2469                 :            :           xze[i] = coordinates[6][i] - coordinates[2][i];
    2470                 :            :   }
    2471                 :            : 
    2472                 :            :   // norm jacobian and jacobian
    2473                 :            :   if( choices[0] || choices[1] )
    2474                 :            :   {
    2475                 :            :     current_jacobian = determinant( xxi, xet, xze );
    2476                 :            :     current_norm_jac = normalize_jacobian( current_jacobian,
    2477                 :            :             xxi, xet, xze );
    2478                 :            : 
    2479                 :            :     if (current_norm_jac < norm_jacobian) { norm_jacobian = current_norm_jac; }
    2480                 :            :     if (current_jacobian < jacobian) { jacobian = current_jacobian; }
    2481                 :            :   }
    2482                 :            : 
    2483                 :            :   // oddy
    2484                 :            :   if( choices[2] )
    2485                 :            :   {
    2486                 :            :     current_oddy = oddy_comp( xxi, xet, xze );
    2487                 :            :       if ( current_oddy > oddy ) { oddy = current_oddy; }
    2488                 :            :   }
    2489                 :            : 
    2490                 :            :   // condition
    2491                 :            :   if( choices[3] )
    2492                 :            :   {
    2493                 :            :     current_condition = condition_comp( xxi, xet, xze );
    2494                 :            :     if ( current_condition > condition ) { condition = current_condition; }
    2495                 :            : 
    2496                 :            :     condition /= 3.0;
    2497                 :            :   }
    2498                 :            : 
    2499                 :            : 
    2500                 :            :   answers[0] = jacobian;
    2501                 :            :   answers[1] = norm_jacobian;
    2502                 :            :   answers[2] = oddy;
    2503                 :            :   answers[3] = condition;
    2504                 :            : 
    2505                 :            :   return 1.0;
    2506                 :            : 
    2507                 :            : }
    2508                 :            : */
    2509                 :            : 
    2510                 :            : /*!
    2511                 :            :   multiple quality metrics of a hex
    2512                 :            : */
    2513                 :          8 : C_FUNC_DEF void v_hex_quality( int num_nodes, double coordinates[][3], unsigned int metrics_request_flag,
    2514                 :            :                                HexMetricVals* metric_vals )
    2515                 :            : {
    2516                 :          8 :     memset( metric_vals, 0, sizeof( HexMetricVals ) );
    2517                 :            : 
    2518                 :            :     // max edge ratio, skew, taper, and volume
    2519         [ +  - ]:          8 :     if( metrics_request_flag & ( V_HEX_MAX_EDGE_RATIO | V_HEX_SKEW | V_HEX_TAPER ) )
    2520                 :            :     {
    2521 [ +  - ][ +  + ]:         72 :         VerdictVector node_pos[8];
    2522 [ +  - ][ +  + ]:         72 :         make_hex_nodes( coordinates, node_pos );
    2523                 :            : 
    2524 [ +  - ][ +  - ]:          8 :         VerdictVector efg1, efg2, efg3;
                 [ +  - ]
    2525 [ +  - ][ +  - ]:          8 :         efg1 = calc_hex_efg( 1, node_pos );
    2526 [ +  - ][ +  - ]:          8 :         efg2 = calc_hex_efg( 2, node_pos );
    2527 [ +  - ][ +  - ]:          8 :         efg3 = calc_hex_efg( 3, node_pos );
    2528                 :            : 
    2529         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_MAX_EDGE_RATIO )
    2530                 :            :         {
    2531                 :            :             double max_edge_ratio_12, max_edge_ratio_13, max_edge_ratio_23;
    2532                 :            : 
    2533         [ +  - ]:          8 :             double mag_efg1 = efg1.length();
    2534         [ +  - ]:          8 :             double mag_efg2 = efg2.length();
    2535         [ +  - ]:          8 :             double mag_efg3 = efg3.length();
    2536                 :            : 
    2537 [ -  + ][ -  + ]:          8 :             max_edge_ratio_12 = safe_ratio( VERDICT_MAX( mag_efg1, mag_efg2 ), VERDICT_MIN( mag_efg1, mag_efg2 ) );
                 [ +  - ]
    2538 [ -  + ][ -  + ]:          8 :             max_edge_ratio_13 = safe_ratio( VERDICT_MAX( mag_efg1, mag_efg3 ), VERDICT_MIN( mag_efg1, mag_efg3 ) );
                 [ +  - ]
    2539 [ -  + ][ -  + ]:          8 :             max_edge_ratio_23 = safe_ratio( VERDICT_MAX( mag_efg2, mag_efg3 ), VERDICT_MIN( mag_efg2, mag_efg3 ) );
                 [ +  - ]
    2540                 :            : 
    2541                 :            :             metric_vals->max_edge_ratio =
    2542 [ -  + ][ -  + ]:          8 :                 (double)VERDICT_MAX( max_edge_ratio_12, VERDICT_MAX( max_edge_ratio_13, max_edge_ratio_23 ) );
                 [ -  + ]
    2543                 :            :         }
    2544                 :            : 
    2545         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_SKEW )
    2546                 :            :         {
    2547                 :            : 
    2548         [ +  - ]:          8 :             VerdictVector vec1 = efg1;
    2549         [ +  - ]:          8 :             VerdictVector vec2 = efg2;
    2550         [ +  - ]:          8 :             VerdictVector vec3 = efg3;
    2551                 :            : 
    2552 [ +  - ][ +  - ]:         16 :             if( vec1.normalize() <= VERDICT_DBL_MIN || vec2.normalize() <= VERDICT_DBL_MIN ||
         [ +  - ][ +  - ]
         [ -  + ][ -  + ]
    2553         [ +  - ]:          8 :                 vec3.normalize() <= VERDICT_DBL_MIN )
    2554                 :          0 :             { metric_vals->skew = (double)VERDICT_DBL_MAX; }
    2555                 :            :             else
    2556                 :            :             {
    2557         [ +  - ]:          8 :                 double skewx = fabs( vec1 % vec2 );
    2558         [ +  - ]:          8 :                 double skewy = fabs( vec1 % vec3 );
    2559         [ +  - ]:          8 :                 double skewz = fabs( vec2 % vec3 );
    2560                 :            : 
    2561 [ -  + ][ -  + ]:          8 :                 metric_vals->skew = (double)( VERDICT_MAX( skewx, VERDICT_MAX( skewy, skewz ) ) );
                 [ -  + ]
    2562                 :            :             }
    2563                 :            :         }
    2564                 :            : 
    2565         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_TAPER )
    2566                 :            :         {
    2567         [ +  - ]:          8 :             VerdictVector efg12 = calc_hex_efg( 12, node_pos );
    2568         [ +  - ]:          8 :             VerdictVector efg13 = calc_hex_efg( 13, node_pos );
    2569         [ +  - ]:          8 :             VerdictVector efg23 = calc_hex_efg( 23, node_pos );
    2570                 :            : 
    2571 [ +  - ][ +  - ]:          8 :             double taperx = fabs( safe_ratio( efg12.length(), VERDICT_MIN( efg1.length(), efg2.length() ) ) );
         [ -  + ][ #  # ]
         [ +  - ][ +  - ]
                 [ +  - ]
    2572 [ +  - ][ +  - ]:          8 :             double tapery = fabs( safe_ratio( efg13.length(), VERDICT_MIN( efg1.length(), efg3.length() ) ) );
         [ -  + ][ #  # ]
         [ +  - ][ +  - ]
                 [ +  - ]
    2573 [ +  - ][ +  - ]:          8 :             double taperz = fabs( safe_ratio( efg23.length(), VERDICT_MIN( efg2.length(), efg3.length() ) ) );
         [ -  + ][ #  # ]
         [ +  - ][ +  - ]
                 [ +  - ]
    2574                 :            : 
    2575 [ -  + ][ -  + ]:          8 :             metric_vals->taper = (double)VERDICT_MAX( taperx, VERDICT_MAX( tapery, taperz ) );
                 [ -  + ]
    2576                 :            :         }
    2577                 :            :     }
    2578                 :            : 
    2579         [ +  - ]:          8 :     if( metrics_request_flag & V_HEX_VOLUME ) { metric_vals->volume = v_hex_volume( 8, coordinates ); }
    2580                 :            : 
    2581         [ +  - ]:          8 :     if( metrics_request_flag &
    2582                 :            :         ( V_HEX_JACOBIAN | V_HEX_SCALED_JACOBIAN | V_HEX_CONDITION | V_HEX_SHEAR | V_HEX_SHAPE |
    2583                 :            :           V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE | V_HEX_STRETCH ) )
    2584                 :            :     {
    2585                 :            : 
    2586                 :            :         static const double two_thirds = 2.0 / 3.0;
    2587 [ +  - ][ +  + ]:        104 :         VerdictVector edges[12];
    2588                 :            :         // the length squares
    2589                 :            :         double length_squared[12];
    2590                 :            :         // make vectors from coordinates
    2591         [ +  - ]:          8 :         make_hex_edges( coordinates, edges );
    2592                 :            : 
    2593                 :            :         // calculate the length squares if we need to
    2594         [ +  - ]:          8 :         if( metrics_request_flag &
    2595                 :            :             ( V_HEX_JACOBIAN | V_HEX_SHEAR | V_HEX_SCALED_JACOBIAN | V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE |
    2596                 :            :               V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHEAR_AND_SIZE | V_HEX_STRETCH ) )
    2597 [ +  - ][ +  + ]:        104 :             make_edge_length_squares( edges, length_squared );
    2598                 :            : 
    2599                 :          8 :         double jacobian = VERDICT_DBL_MAX, scaled_jacobian = VERDICT_DBL_MAX, condition = 0.0, shear = 1.0, shape = 1.0,
    2600                 :          8 :                oddy = 0.0;
    2601                 :          8 :         double current_jacobian, current_scaled_jacobian, current_condition, current_shape, detw = 0, det_sum = 0,
    2602                 :            :                                                                                             current_oddy;
    2603                 :          8 :         VerdictBoolean rel_size_error = VERDICT_FALSE;
    2604                 :            : 
    2605 [ +  - ][ +  - ]:          8 :         VerdictVector xxi, xet, xze;
                 [ +  - ]
    2606                 :            : 
    2607                 :            :         // get weights if we need based on average size of a hex
    2608         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) )
    2609                 :            :         {
    2610         [ +  - ]:          8 :             v_hex_get_weight( xxi, xet, xze );
    2611 [ +  - ][ +  - ]:          8 :             detw = xxi % ( xet * xze );
    2612         [ -  + ]:          8 :             if( detw < VERDICT_DBL_MIN ) rel_size_error = VERDICT_TRUE;
    2613                 :            :         }
    2614                 :            : 
    2615 [ +  - ][ +  - ]:          8 :         xxi = edges[0] - edges[2] + edges[4] - edges[6];
         [ +  - ][ +  - ]
    2616 [ +  - ][ +  - ]:          8 :         xet = edges[1] - edges[3] + edges[5] - edges[7];
         [ +  - ][ +  - ]
    2617 [ +  - ][ +  - ]:          8 :         xze = edges[8] + edges[9] + edges[10] + edges[11];
         [ +  - ][ +  - ]
    2618                 :            : 
    2619 [ +  - ][ +  - ]:          8 :         current_jacobian = xxi % ( xet * xze ) / 64.0;
    2620         [ +  - ]:          8 :         if( current_jacobian < jacobian ) jacobian = current_jacobian;
    2621                 :            : 
    2622         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) )
    2623                 :            :         {
    2624                 :          8 :             current_jacobian *= 64.0;
    2625                 :            :             current_scaled_jacobian =
    2626 [ +  - ][ +  - ]:          8 :                 current_jacobian / sqrt( xxi.length_squared() * xet.length_squared() * xze.length_squared() );
                 [ +  - ]
    2627         [ +  - ]:          8 :             if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian;
    2628                 :            :         }
    2629                 :            : 
    2630         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_CONDITION )
    2631                 :            :         {
    2632         [ +  - ]:          8 :             current_condition = condition_comp( xxi, xet, xze );
    2633         [ +  - ]:          8 :             if( current_condition > condition ) { condition = current_condition; }
    2634                 :            :         }
    2635                 :            : 
    2636         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_ODDY )
    2637                 :            :         {
    2638         [ +  - ]:          8 :             current_oddy = oddy_comp( xxi, xet, xze );
    2639         [ -  + ]:          8 :             if( current_oddy > oddy ) { oddy = current_oddy; }
    2640                 :            :         }
    2641                 :            : 
    2642                 :            :         // J(0,0,0)
    2643 [ +  - ][ +  - ]:          8 :         current_jacobian = edges[0] % ( -edges[3] * edges[8] );
                 [ +  - ]
    2644         [ -  + ]:          8 :         if( current_jacobian < jacobian ) jacobian = current_jacobian;
    2645                 :            : 
    2646         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) )
    2647                 :          8 :         { det_sum += current_jacobian; }
    2648                 :            : 
    2649         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) )
    2650                 :            :         {
    2651 [ +  - ][ +  - ]:          8 :             if( length_squared[0] <= VERDICT_DBL_MIN || length_squared[3] <= VERDICT_DBL_MIN ||
                 [ -  + ]
    2652                 :          8 :                 length_squared[8] <= VERDICT_DBL_MIN )
    2653                 :          0 :             { current_scaled_jacobian = VERDICT_DBL_MAX; }
    2654                 :            :             else
    2655                 :            :             {
    2656                 :            :                 current_scaled_jacobian =
    2657                 :          8 :                     current_jacobian / sqrt( length_squared[0] * length_squared[3] * length_squared[8] );
    2658                 :            :             }
    2659         [ -  + ]:          8 :             if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian;
    2660                 :            :         }
    2661                 :            : 
    2662         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_CONDITION )
    2663                 :            :         {
    2664 [ +  - ][ +  - ]:          8 :             current_condition = condition_comp( edges[0], -edges[3], edges[8] );
    2665         [ -  + ]:          8 :             if( current_condition > condition ) { condition = current_condition; }
    2666                 :            :         }
    2667                 :            : 
    2668         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_ODDY )
    2669                 :            :         {
    2670 [ +  - ][ +  - ]:          8 :             current_oddy = oddy_comp( edges[0], -edges[3], edges[8] );
    2671         [ -  + ]:          8 :             if( current_oddy > oddy ) { oddy = current_oddy; }
    2672                 :            :         }
    2673                 :            : 
    2674         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) )
    2675                 :            :         {
    2676         [ +  - ]:          8 :             if( current_jacobian > VERDICT_DBL_MIN )
    2677                 :          8 :                 current_shape = 3 * pow( current_jacobian, two_thirds ) /
    2678                 :          8 :                                 ( length_squared[0] + length_squared[3] + length_squared[8] );
    2679                 :            :             else
    2680                 :          0 :                 current_shape = 0;
    2681                 :            : 
    2682         [ -  + ]:          8 :             if( current_shape < shape ) { shape = current_shape; }
    2683                 :            :         }
    2684                 :            : 
    2685                 :            :         // J(1,0,0)
    2686 [ +  - ][ +  - ]:          8 :         current_jacobian = edges[1] % ( -edges[0] * edges[9] );
                 [ +  - ]
    2687         [ -  + ]:          8 :         if( current_jacobian < jacobian ) jacobian = current_jacobian;
    2688                 :            : 
    2689         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) )
    2690                 :          8 :         { det_sum += current_jacobian; }
    2691                 :            : 
    2692         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) )
    2693                 :            :         {
    2694 [ +  - ][ +  - ]:          8 :             if( length_squared[1] <= VERDICT_DBL_MIN || length_squared[0] <= VERDICT_DBL_MIN ||
                 [ -  + ]
    2695                 :          8 :                 length_squared[9] <= VERDICT_DBL_MIN )
    2696                 :          0 :             { current_scaled_jacobian = VERDICT_DBL_MAX; }
    2697                 :            :             else
    2698                 :            :             {
    2699                 :            :                 current_scaled_jacobian =
    2700                 :          8 :                     current_jacobian / sqrt( length_squared[1] * length_squared[0] * length_squared[9] );
    2701                 :            :             }
    2702         [ -  + ]:          8 :             if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian;
    2703                 :            :         }
    2704                 :            : 
    2705         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_CONDITION )
    2706                 :            :         {
    2707 [ +  - ][ +  - ]:          8 :             current_condition = condition_comp( edges[1], -edges[0], edges[9] );
    2708         [ -  + ]:          8 :             if( current_condition > condition ) { condition = current_condition; }
    2709                 :            :         }
    2710                 :            : 
    2711         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_ODDY )
    2712                 :            :         {
    2713 [ +  - ][ +  - ]:          8 :             current_oddy = oddy_comp( edges[1], -edges[0], edges[9] );
    2714         [ -  + ]:          8 :             if( current_oddy > oddy ) { oddy = current_oddy; }
    2715                 :            :         }
    2716                 :            : 
    2717         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) )
    2718                 :            :         {
    2719         [ +  - ]:          8 :             if( current_jacobian > VERDICT_DBL_MIN )
    2720                 :          8 :                 current_shape = 3 * pow( current_jacobian, two_thirds ) /
    2721                 :          8 :                                 ( length_squared[1] + length_squared[0] + length_squared[9] );
    2722                 :            :             else
    2723                 :          0 :                 current_shape = 0;
    2724                 :            : 
    2725         [ -  + ]:          8 :             if( current_shape < shape ) { shape = current_shape; }
    2726                 :            :         }
    2727                 :            : 
    2728                 :            :         // J(1,1,0)
    2729 [ +  - ][ +  - ]:          8 :         current_jacobian = edges[2] % ( -edges[1] * edges[10] );
                 [ +  - ]
    2730         [ -  + ]:          8 :         if( current_jacobian < jacobian ) jacobian = current_jacobian;
    2731                 :            : 
    2732         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) )
    2733                 :          8 :         { det_sum += current_jacobian; }
    2734                 :            : 
    2735         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) )
    2736                 :            :         {
    2737 [ +  - ][ +  - ]:          8 :             if( length_squared[2] <= VERDICT_DBL_MIN || length_squared[1] <= VERDICT_DBL_MIN ||
                 [ -  + ]
    2738                 :          8 :                 length_squared[10] <= VERDICT_DBL_MIN )
    2739                 :          0 :             { current_scaled_jacobian = VERDICT_DBL_MAX; }
    2740                 :            :             else
    2741                 :            :             {
    2742                 :            :                 current_scaled_jacobian =
    2743                 :          8 :                     current_jacobian / sqrt( length_squared[2] * length_squared[1] * length_squared[10] );
    2744                 :            :             }
    2745         [ -  + ]:          8 :             if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian;
    2746                 :            :         }
    2747                 :            : 
    2748         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_CONDITION )
    2749                 :            :         {
    2750 [ +  - ][ +  - ]:          8 :             current_condition = condition_comp( edges[2], -edges[1], edges[10] );
    2751         [ -  + ]:          8 :             if( current_condition > condition ) { condition = current_condition; }
    2752                 :            :         }
    2753                 :            : 
    2754         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_ODDY )
    2755                 :            :         {
    2756 [ +  - ][ +  - ]:          8 :             current_oddy = oddy_comp( edges[2], -edges[1], edges[10] );
    2757         [ -  + ]:          8 :             if( current_oddy > oddy ) { oddy = current_oddy; }
    2758                 :            :         }
    2759                 :            : 
    2760         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) )
    2761                 :            :         {
    2762         [ +  - ]:          8 :             if( current_jacobian > VERDICT_DBL_MIN )
    2763                 :          8 :                 current_shape = 3 * pow( current_jacobian, two_thirds ) /
    2764                 :          8 :                                 ( length_squared[2] + length_squared[1] + length_squared[10] );
    2765                 :            :             else
    2766                 :          0 :                 current_shape = 0;
    2767                 :            : 
    2768         [ -  + ]:          8 :             if( current_shape < shape ) { shape = current_shape; }
    2769                 :            :         }
    2770                 :            : 
    2771                 :            :         // J(0,1,0)
    2772 [ +  - ][ +  - ]:          8 :         current_jacobian = edges[3] % ( -edges[2] * edges[11] );
                 [ +  - ]
    2773         [ -  + ]:          8 :         if( current_jacobian < jacobian ) jacobian = current_jacobian;
    2774                 :            : 
    2775         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) )
    2776                 :          8 :         { det_sum += current_jacobian; }
    2777                 :            : 
    2778         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) )
    2779                 :            :         {
    2780 [ +  - ][ +  - ]:          8 :             if( length_squared[3] <= VERDICT_DBL_MIN || length_squared[2] <= VERDICT_DBL_MIN ||
                 [ -  + ]
    2781                 :          8 :                 length_squared[11] <= VERDICT_DBL_MIN )
    2782                 :          0 :             { current_scaled_jacobian = VERDICT_DBL_MAX; }
    2783                 :            :             else
    2784                 :            :             {
    2785                 :            :                 current_scaled_jacobian =
    2786                 :          8 :                     current_jacobian / sqrt( length_squared[3] * length_squared[2] * length_squared[11] );
    2787                 :            :             }
    2788         [ -  + ]:          8 :             if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian;
    2789                 :            :         }
    2790                 :            : 
    2791         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_CONDITION )
    2792                 :            :         {
    2793 [ +  - ][ +  - ]:          8 :             current_condition = condition_comp( edges[3], -edges[2], edges[11] );
    2794         [ -  + ]:          8 :             if( current_condition > condition ) { condition = current_condition; }
    2795                 :            :         }
    2796                 :            : 
    2797         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_ODDY )
    2798                 :            :         {
    2799 [ +  - ][ +  - ]:          8 :             current_oddy = oddy_comp( edges[3], -edges[2], edges[11] );
    2800         [ -  + ]:          8 :             if( current_oddy > oddy ) { oddy = current_oddy; }
    2801                 :            :         }
    2802                 :            : 
    2803         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) )
    2804                 :            :         {
    2805         [ +  - ]:          8 :             if( current_jacobian > VERDICT_DBL_MIN )
    2806                 :          8 :                 current_shape = 3 * pow( current_jacobian, two_thirds ) /
    2807                 :          8 :                                 ( length_squared[3] + length_squared[2] + length_squared[11] );
    2808                 :            :             else
    2809                 :          0 :                 current_shape = 0;
    2810                 :            : 
    2811         [ -  + ]:          8 :             if( current_shape < shape ) { shape = current_shape; }
    2812                 :            :         }
    2813                 :            : 
    2814                 :            :         // J(0,0,1)
    2815 [ +  - ][ +  - ]:          8 :         current_jacobian = edges[4] % ( -edges[8] * -edges[7] );
         [ +  - ][ +  - ]
    2816         [ -  + ]:          8 :         if( current_jacobian < jacobian ) jacobian = current_jacobian;
    2817                 :            : 
    2818         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) )
    2819                 :          8 :         { det_sum += current_jacobian; }
    2820                 :            : 
    2821         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) )
    2822                 :            :         {
    2823 [ +  - ][ +  - ]:          8 :             if( length_squared[4] <= VERDICT_DBL_MIN || length_squared[8] <= VERDICT_DBL_MIN ||
                 [ -  + ]
    2824                 :          8 :                 length_squared[7] <= VERDICT_DBL_MIN )
    2825                 :          0 :             { current_scaled_jacobian = VERDICT_DBL_MAX; }
    2826                 :            :             else
    2827                 :            :             {
    2828                 :            :                 current_scaled_jacobian =
    2829                 :          8 :                     current_jacobian / sqrt( length_squared[4] * length_squared[8] * length_squared[7] );
    2830                 :            :             }
    2831         [ -  + ]:          8 :             if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian;
    2832                 :            :         }
    2833                 :            : 
    2834         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_CONDITION )
    2835                 :            :         {
    2836 [ +  - ][ +  - ]:          8 :             current_condition = condition_comp( edges[4], -edges[8], -edges[7] );
                 [ +  - ]
    2837         [ -  + ]:          8 :             if( current_condition > condition ) { condition = current_condition; }
    2838                 :            :         }
    2839                 :            : 
    2840         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_ODDY )
    2841                 :            :         {
    2842 [ +  - ][ +  - ]:          8 :             current_oddy = oddy_comp( edges[4], -edges[8], -edges[7] );
                 [ +  - ]
    2843         [ -  + ]:          8 :             if( current_oddy > oddy ) { oddy = current_oddy; }
    2844                 :            :         }
    2845                 :            : 
    2846         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) )
    2847                 :            :         {
    2848         [ +  - ]:          8 :             if( current_jacobian > VERDICT_DBL_MIN )
    2849                 :          8 :                 current_shape = 3 * pow( current_jacobian, two_thirds ) /
    2850                 :          8 :                                 ( length_squared[4] + length_squared[8] + length_squared[7] );
    2851                 :            :             else
    2852                 :          0 :                 current_shape = 0;
    2853                 :            : 
    2854         [ -  + ]:          8 :             if( current_shape < shape ) { shape = current_shape; }
    2855                 :            :         }
    2856                 :            : 
    2857                 :            :         // J(1,0,1)
    2858 [ +  - ][ +  - ]:          8 :         current_jacobian = -edges[4] % ( edges[5] * -edges[9] );
         [ +  - ][ +  - ]
    2859         [ -  + ]:          8 :         if( current_jacobian < jacobian ) jacobian = current_jacobian;
    2860                 :            : 
    2861         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) )
    2862                 :          8 :         { det_sum += current_jacobian; }
    2863                 :            : 
    2864         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) )
    2865                 :            :         {
    2866 [ +  - ][ +  - ]:          8 :             if( length_squared[4] <= VERDICT_DBL_MIN || length_squared[5] <= VERDICT_DBL_MIN ||
                 [ -  + ]
    2867                 :          8 :                 length_squared[9] <= VERDICT_DBL_MIN )
    2868                 :          0 :             { current_scaled_jacobian = VERDICT_DBL_MAX; }
    2869                 :            :             else
    2870                 :            :             {
    2871                 :            :                 current_scaled_jacobian =
    2872                 :          8 :                     current_jacobian / sqrt( length_squared[4] * length_squared[5] * length_squared[9] );
    2873                 :            :             }
    2874         [ -  + ]:          8 :             if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian;
    2875                 :            :         }
    2876                 :            : 
    2877         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_CONDITION )
    2878                 :            :         {
    2879 [ +  - ][ +  - ]:          8 :             current_condition = condition_comp( -edges[4], edges[5], -edges[9] );
                 [ +  - ]
    2880         [ -  + ]:          8 :             if( current_condition > condition ) { condition = current_condition; }
    2881                 :            :         }
    2882                 :            : 
    2883         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_ODDY )
    2884                 :            :         {
    2885 [ +  - ][ +  - ]:          8 :             current_oddy = oddy_comp( -edges[4], edges[5], -edges[9] );
                 [ +  - ]
    2886         [ -  + ]:          8 :             if( current_oddy > oddy ) { oddy = current_oddy; }
    2887                 :            :         }
    2888                 :            : 
    2889         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) )
    2890                 :            :         {
    2891         [ +  - ]:          8 :             if( current_jacobian > VERDICT_DBL_MIN )
    2892                 :          8 :                 current_shape = 3 * pow( current_jacobian, two_thirds ) /
    2893                 :          8 :                                 ( length_squared[4] + length_squared[5] + length_squared[9] );
    2894                 :            :             else
    2895                 :          0 :                 current_shape = 0;
    2896                 :            : 
    2897         [ -  + ]:          8 :             if( current_shape < shape ) { shape = current_shape; }
    2898                 :            :         }
    2899                 :            : 
    2900                 :            :         // J(1,1,1)
    2901 [ +  - ][ +  - ]:          8 :         current_jacobian = -edges[5] % ( edges[6] * -edges[10] );
         [ +  - ][ +  - ]
    2902         [ -  + ]:          8 :         if( current_jacobian < jacobian ) jacobian = current_jacobian;
    2903                 :            : 
    2904         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) )
    2905                 :          8 :         { det_sum += current_jacobian; }
    2906                 :            : 
    2907         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) )
    2908                 :            :         {
    2909 [ +  - ][ +  - ]:          8 :             if( length_squared[5] <= VERDICT_DBL_MIN || length_squared[6] <= VERDICT_DBL_MIN ||
                 [ -  + ]
    2910                 :          8 :                 length_squared[10] <= VERDICT_DBL_MIN )
    2911                 :          0 :             { current_scaled_jacobian = VERDICT_DBL_MAX; }
    2912                 :            :             else
    2913                 :            :             {
    2914                 :            :                 current_scaled_jacobian =
    2915                 :          8 :                     current_jacobian / sqrt( length_squared[5] * length_squared[6] * length_squared[10] );
    2916                 :            :             }
    2917         [ -  + ]:          8 :             if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian;
    2918                 :            :         }
    2919                 :            : 
    2920         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_CONDITION )
    2921                 :            :         {
    2922 [ +  - ][ +  - ]:          8 :             current_condition = condition_comp( -edges[5], edges[6], -edges[10] );
                 [ +  - ]
    2923         [ -  + ]:          8 :             if( current_condition > condition ) { condition = current_condition; }
    2924                 :            :         }
    2925                 :            : 
    2926         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_ODDY )
    2927                 :            :         {
    2928 [ +  - ][ +  - ]:          8 :             current_oddy = oddy_comp( -edges[5], edges[6], -edges[10] );
                 [ +  - ]
    2929         [ -  + ]:          8 :             if( current_oddy > oddy ) { oddy = current_oddy; }
    2930                 :            :         }
    2931                 :            : 
    2932         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) )
    2933                 :            :         {
    2934         [ +  - ]:          8 :             if( current_jacobian > VERDICT_DBL_MIN )
    2935                 :          8 :                 current_shape = 3 * pow( current_jacobian, two_thirds ) /
    2936                 :          8 :                                 ( length_squared[5] + length_squared[6] + length_squared[10] );
    2937                 :            :             else
    2938                 :          0 :                 current_shape = 0;
    2939                 :            : 
    2940         [ -  + ]:          8 :             if( current_shape < shape ) { shape = current_shape; }
    2941                 :            :         }
    2942                 :            : 
    2943                 :            :         // J(0,1,1)
    2944 [ +  - ][ +  - ]:          8 :         current_jacobian = -edges[6] % ( edges[7] * -edges[11] );
         [ +  - ][ +  - ]
    2945         [ -  + ]:          8 :         if( current_jacobian < jacobian ) jacobian = current_jacobian;
    2946                 :            : 
    2947         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) )
    2948                 :          8 :         { det_sum += current_jacobian; }
    2949                 :            : 
    2950         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SCALED_JACOBIAN | V_HEX_SHEAR | V_HEX_SHEAR_AND_SIZE ) )
    2951                 :            :         {
    2952 [ +  - ][ +  - ]:          8 :             if( length_squared[6] <= VERDICT_DBL_MIN || length_squared[7] <= VERDICT_DBL_MIN ||
                 [ -  + ]
    2953                 :          8 :                 length_squared[11] <= VERDICT_DBL_MIN )
    2954                 :          0 :             { current_scaled_jacobian = VERDICT_DBL_MAX; }
    2955                 :            :             else
    2956                 :            :             {
    2957                 :            :                 current_scaled_jacobian =
    2958                 :          8 :                     current_jacobian / sqrt( length_squared[6] * length_squared[7] * length_squared[11] );
    2959                 :            :             }
    2960         [ -  + ]:          8 :             if( current_scaled_jacobian < scaled_jacobian ) shear = scaled_jacobian = current_scaled_jacobian;
    2961                 :            :         }
    2962                 :            : 
    2963         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_CONDITION )
    2964                 :            :         {
    2965 [ +  - ][ +  - ]:          8 :             current_condition = condition_comp( -edges[6], edges[7], -edges[11] );
                 [ +  - ]
    2966         [ -  + ]:          8 :             if( current_condition > condition ) { condition = current_condition; }
    2967                 :            :         }
    2968                 :            : 
    2969         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_ODDY )
    2970                 :            :         {
    2971 [ +  - ][ +  - ]:          8 :             current_oddy = oddy_comp( -edges[6], edges[7], -edges[11] );
                 [ +  - ]
    2972         [ -  + ]:          8 :             if( current_oddy > oddy ) { oddy = current_oddy; }
    2973                 :            :         }
    2974                 :            : 
    2975         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_SHAPE | V_HEX_SHAPE_AND_SIZE ) )
    2976                 :            :         {
    2977         [ +  - ]:          8 :             if( current_jacobian > VERDICT_DBL_MIN )
    2978                 :          8 :                 current_shape = 3 * pow( current_jacobian, two_thirds ) /
    2979                 :          8 :                                 ( length_squared[6] + length_squared[7] + length_squared[11] );
    2980                 :            :             else
    2981                 :          0 :                 current_shape = 0;
    2982                 :            : 
    2983         [ -  + ]:          8 :             if( current_shape < shape ) { shape = current_shape; }
    2984                 :            :         }
    2985                 :            : 
    2986         [ +  - ]:          8 :         if( metrics_request_flag & ( V_HEX_RELATIVE_SIZE_SQUARED | V_HEX_SHAPE_AND_SIZE | V_HEX_SHEAR_AND_SIZE ) )
    2987                 :            :         {
    2988 [ +  - ][ +  - ]:          8 :             if( det_sum > VERDICT_DBL_MIN && rel_size_error != VERDICT_TRUE )
    2989                 :            :             {
    2990                 :          8 :                 double tau                         = det_sum / ( 8 * detw );
    2991         [ +  - ]:          8 :                 metric_vals->relative_size_squared = (double)VERDICT_MIN( tau * tau, 1.0 / tau / tau );
    2992                 :            :             }
    2993                 :            :             else
    2994                 :          8 :                 metric_vals->relative_size_squared = 0.0;
    2995                 :            :         }
    2996                 :            : 
    2997                 :            :         // set values from above calculations
    2998         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_JACOBIAN ) metric_vals->jacobian = (double)jacobian;
    2999                 :            : 
    3000         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_SCALED_JACOBIAN ) metric_vals->scaled_jacobian = (double)scaled_jacobian;
    3001                 :            : 
    3002         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_CONDITION ) metric_vals->condition = (double)( condition / 3.0 );
    3003                 :            : 
    3004         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_SHEAR )
    3005                 :            :         {
    3006         [ -  + ]:          8 :             if( shear < VERDICT_DBL_MIN )  // shear has range 0 to +1
    3007                 :          0 :                 shear = 0;
    3008                 :          8 :             metric_vals->shear = (double)shear;
    3009                 :            :         }
    3010                 :            : 
    3011         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_SHAPE ) metric_vals->shape = (double)shape;
    3012                 :            : 
    3013         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_SHAPE_AND_SIZE )
    3014                 :          8 :             metric_vals->shape_and_size = (double)( shape * metric_vals->relative_size_squared );
    3015                 :            : 
    3016         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_SHEAR_AND_SIZE )
    3017                 :          8 :             metric_vals->shear_and_size = (double)( shear * metric_vals->relative_size_squared );
    3018                 :            : 
    3019         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_ODDY ) metric_vals->oddy = (double)oddy;
    3020                 :            : 
    3021         [ +  - ]:          8 :         if( metrics_request_flag & V_HEX_STRETCH )
    3022                 :            :         {
    3023                 :            :             static const double HEX_STRETCH_SCALE_FACTOR = sqrt( 3.0 );
    3024                 :          8 :             double min_edge                              = length_squared[0];
    3025         [ +  + ]:         96 :             for( int j = 1; j < 12; j++ )
    3026         [ -  + ]:         88 :                 min_edge = VERDICT_MIN( min_edge, length_squared[j] );
    3027                 :            : 
    3028         [ +  - ]:          8 :             double max_diag = diag_length( 1, coordinates );
    3029                 :            : 
    3030         [ +  - ]:          8 :             metric_vals->stretch = (double)( HEX_STRETCH_SCALE_FACTOR * ( safe_ratio( sqrt( min_edge ), max_diag ) ) );
    3031                 :            :         }
    3032                 :            :     }
    3033                 :            : 
    3034         [ +  - ]:          8 :     if( metrics_request_flag & V_HEX_DIAGONAL ) metric_vals->diagonal = v_hex_diagonal( num_nodes, coordinates );
    3035         [ +  - ]:          8 :     if( metrics_request_flag & V_HEX_DIMENSION ) metric_vals->dimension = v_hex_dimension( num_nodes, coordinates );
    3036         [ +  - ]:          8 :     if( metrics_request_flag & V_HEX_DISTORTION ) metric_vals->distortion = v_hex_distortion( num_nodes, coordinates );
    3037                 :            : 
    3038                 :            :     // take care of any overflow problems
    3039                 :            :     // max_edge_ratio
    3040         [ +  - ]:          8 :     if( metric_vals->max_edge_ratio > 0 )
    3041         [ +  - ]:          8 :         metric_vals->max_edge_ratio = (double)VERDICT_MIN( metric_vals->max_edge_ratio, VERDICT_DBL_MAX );
    3042                 :            :     else
    3043         [ #  # ]:          0 :         metric_vals->max_edge_ratio = (double)VERDICT_MAX( metric_vals->max_edge_ratio, -VERDICT_DBL_MAX );
    3044                 :            : 
    3045                 :            :     // skew
    3046         [ -  + ]:          8 :     if( metric_vals->skew > 0 )
    3047         [ #  # ]:          0 :         metric_vals->skew = (double)VERDICT_MIN( metric_vals->skew, VERDICT_DBL_MAX );
    3048                 :            :     else
    3049         [ +  - ]:          8 :         metric_vals->skew = (double)VERDICT_MAX( metric_vals->skew, -VERDICT_DBL_MAX );
    3050                 :            : 
    3051                 :            :     // taper
    3052         [ -  + ]:          8 :     if( metric_vals->taper > 0 )
    3053         [ #  # ]:          0 :         metric_vals->taper = (double)VERDICT_MIN( metric_vals->taper, VERDICT_DBL_MAX );
    3054                 :            :     else
    3055         [ +  - ]:          8 :         metric_vals->taper = (double)VERDICT_MAX( metric_vals->taper, -VERDICT_DBL_MAX );
    3056                 :            : 
    3057                 :            :     // volume
    3058         [ +  - ]:          8 :     if( metric_vals->volume > 0 )
    3059         [ +  - ]:          8 :         metric_vals->volume = (double)VERDICT_MIN( metric_vals->volume, VERDICT_DBL_MAX );
    3060                 :            :     else
    3061         [ #  # ]:          0 :         metric_vals->volume = (double)VERDICT_MAX( metric_vals->volume, -VERDICT_DBL_MAX );
    3062                 :            : 
    3063                 :            :     // stretch
    3064         [ +  - ]:          8 :     if( metric_vals->stretch > 0 )
    3065         [ +  - ]:          8 :         metric_vals->stretch = (double)VERDICT_MIN( metric_vals->stretch, VERDICT_DBL_MAX );
    3066                 :            :     else
    3067         [ #  # ]:          0 :         metric_vals->stretch = (double)VERDICT_MAX( metric_vals->stretch, -VERDICT_DBL_MAX );
    3068                 :            : 
    3069                 :            :     // diagonal
    3070         [ +  - ]:          8 :     if( metric_vals->diagonal > 0 )
    3071         [ +  - ]:          8 :         metric_vals->diagonal = (double)VERDICT_MIN( metric_vals->diagonal, VERDICT_DBL_MAX );
    3072                 :            :     else
    3073         [ #  # ]:          0 :         metric_vals->diagonal = (double)VERDICT_MAX( metric_vals->diagonal, -VERDICT_DBL_MAX );
    3074                 :            : 
    3075                 :            :     // dimension
    3076         [ +  - ]:          8 :     if( metric_vals->dimension > 0 )
    3077         [ +  - ]:          8 :         metric_vals->dimension = (double)VERDICT_MIN( metric_vals->dimension, VERDICT_DBL_MAX );
    3078                 :            :     else
    3079         [ #  # ]:          0 :         metric_vals->dimension = (double)VERDICT_MAX( metric_vals->dimension, -VERDICT_DBL_MAX );
    3080                 :            : 
    3081                 :            :     // oddy
    3082         [ -  + ]:          8 :     if( metric_vals->oddy > 0 )
    3083         [ #  # ]:          0 :         metric_vals->oddy = (double)VERDICT_MIN( metric_vals->oddy, VERDICT_DBL_MAX );
    3084                 :            :     else
    3085         [ +  - ]:          8 :         metric_vals->oddy = (double)VERDICT_MAX( metric_vals->oddy, -VERDICT_DBL_MAX );
    3086                 :            : 
    3087                 :            :     // condition
    3088         [ +  - ]:          8 :     if( metric_vals->condition > 0 )
    3089         [ +  - ]:          8 :         metric_vals->condition = (double)VERDICT_MIN( metric_vals->condition, VERDICT_DBL_MAX );
    3090                 :            :     else
    3091         [ #  # ]:          0 :         metric_vals->condition = (double)VERDICT_MAX( metric_vals->condition, -VERDICT_DBL_MAX );
    3092                 :            : 
    3093                 :            :     // jacobian
    3094         [ +  - ]:          8 :     if( metric_vals->jacobian > 0 )
    3095         [ +  - ]:          8 :         metric_vals->jacobian = (double)VERDICT_MIN( metric_vals->jacobian, VERDICT_DBL_MAX );
    3096                 :            :     else
    3097         [ #  # ]:          0 :         metric_vals->jacobian = (double)VERDICT_MAX( metric_vals->jacobian, -VERDICT_DBL_MAX );
    3098                 :            : 
    3099                 :            :     // scaled_jacobian
    3100         [ +  - ]:          8 :     if( metric_vals->scaled_jacobian > 0 )
    3101         [ +  - ]:          8 :         metric_vals->scaled_jacobian = (double)VERDICT_MIN( metric_vals->scaled_jacobian, VERDICT_DBL_MAX );
    3102                 :            :     else
    3103         [ #  # ]:          0 :         metric_vals->scaled_jacobian = (double)VERDICT_MAX( metric_vals->scaled_jacobian, -VERDICT_DBL_MAX );
    3104                 :            : 
    3105                 :            :     // shear
    3106         [ +  - ]:          8 :     if( metric_vals->shear > 0 )
    3107         [ +  - ]:          8 :         metric_vals->shear = (double)VERDICT_MIN( metric_vals->shear, VERDICT_DBL_MAX );
    3108                 :            :     else
    3109         [ #  # ]:          0 :         metric_vals->shear = (double)VERDICT_MAX( metric_vals->shear, -VERDICT_DBL_MAX );
    3110                 :            : 
    3111                 :            :     // shape
    3112         [ +  - ]:          8 :     if( metric_vals->shape > 0 )
    3113         [ +  - ]:          8 :         metric_vals->shape = (double)VERDICT_MIN( metric_vals->shape, VERDICT_DBL_MAX );
    3114                 :            :     else
    3115         [ #  # ]:          0 :         metric_vals->shape = (double)VERDICT_MAX( metric_vals->shape, -VERDICT_DBL_MAX );
    3116                 :            : 
    3117                 :            :     // relative_size_squared
    3118         [ +  - ]:          8 :     if( metric_vals->relative_size_squared > 0 )
    3119         [ +  - ]:          8 :         metric_vals->relative_size_squared = (double)VERDICT_MIN( metric_vals->relative_size_squared, VERDICT_DBL_MAX );
    3120                 :            :     else
    3121                 :            :         metric_vals->relative_size_squared =
    3122         [ #  # ]:          0 :             (double)VERDICT_MAX( metric_vals->relative_size_squared, -VERDICT_DBL_MAX );
    3123                 :            : 
    3124                 :            :     // shape_and_size
    3125         [ +  - ]:          8 :     if( metric_vals->shape_and_size > 0 )
    3126         [ +  - ]:          8 :         metric_vals->shape_and_size = (double)VERDICT_MIN( metric_vals->shape_and_size, VERDICT_DBL_MAX );
    3127                 :            :     else
    3128         [ #  # ]:          0 :         metric_vals->shape_and_size = (double)VERDICT_MAX( metric_vals->shape_and_size, -VERDICT_DBL_MAX );
    3129                 :            : 
    3130                 :            :     // shear_and_size
    3131         [ +  - ]:          8 :     if( metric_vals->shear_and_size > 0 )
    3132         [ +  - ]:          8 :         metric_vals->shear_and_size = (double)VERDICT_MIN( metric_vals->shear_and_size, VERDICT_DBL_MAX );
    3133                 :            :     else
    3134         [ #  # ]:          0 :         metric_vals->shear_and_size = (double)VERDICT_MAX( metric_vals->shear_and_size, -VERDICT_DBL_MAX );
    3135                 :            : 
    3136                 :            :     // distortion
    3137         [ +  - ]:          8 :     if( metric_vals->distortion > 0 )
    3138         [ +  - ]:          8 :         metric_vals->distortion = (double)VERDICT_MIN( metric_vals->distortion, VERDICT_DBL_MAX );
    3139                 :            :     else
    3140         [ #  # ]:          0 :         metric_vals->distortion = (double)VERDICT_MAX( metric_vals->distortion, -VERDICT_DBL_MAX );
    3141                 :            : 
    3142         [ +  - ]:          8 :     if( metrics_request_flag & V_HEX_MED_ASPECT_FROBENIUS )
    3143                 :          8 :         metric_vals->med_aspect_frobenius = v_hex_med_aspect_frobenius( 8, coordinates );
    3144                 :            : 
    3145         [ +  - ]:          8 :     if( metrics_request_flag & V_HEX_EDGE_RATIO ) metric_vals->edge_ratio = v_hex_edge_ratio( 8, coordinates );
    3146                 :          8 : }

Generated by: LCOV version 1.11