1 /*
2  * VerdictWrapper.cpp
3  *
4  *  Created on: Nov 18, 2014
5  *
6  */
7 
8 #include "moab/Interface.hpp"
9 #include "moab/verdict/VerdictWrapper.hpp"
10 #include "Internals.hpp"
11 #include "moab/verdict.h"
12 
13 namespace moab
14 {
VerdictWrapper(Interface * mb)15 VerdictWrapper::VerdictWrapper(Interface * mb) :mbImpl(mb) {
16   // TODO Auto-generated constructor stub
17 
18 }
19 
~VerdictWrapper()20 VerdictWrapper::~VerdictWrapper() {
21   // TODO Auto-generated destructor stub
22 }
23 
24 static int possibleQuality[MBMAXTYPE][MB_QUALITY_COUNT] = {
25     /*
26       MB_EDGE_RATIO = 0,  // 0
27       |  MB_MAX_EDGE_RATIO , // 1
28       |  |  MB_SKEW,            // 2
29       |  |  |  MB_TAPER,           // 3
30       |  |  |  |  MB_VOLUME,          // 4
31       |  |  |  |  |  MB_STRETCH,         // 5
32       |  |  |  |  |  |  MB_DIAGONAL,        // 6
33       |  |  |  |  |  |  |  MB_DIMENSION,       // 7
34       |  |  |  |  |  |  |  |  MB_ODDY,            // 8
35       |  |  |  |  |  |  |  |  |  MB_MED_ASPECT_FROBENIUS,// 9
36       |  |  |  |  |  |  |  |  |  |  MB_MAX_ASPECT_FROBENIUS, // 10
37       |  |  |  |  |  |  |  |  |  |  |  MB_CONDITION,       // 11
38       |  |  |  |  |  |  |  |  |  |  |  |  MB_JACOBIAN,        // 12
39       |  |  |  |  |  |  |  |  |  |  |  |  |  MB_SCALED_JACOBIAN, // 13
40       |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_SHEAR,           // 14
41       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_SHAPE,           // 15
42       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_RELATIVE_SIZE_SQUARED, // 16
43       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_SHAPE_AND_SIZE,        // 17
44       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_SHEAR_AND_SIZE,        // 18
45       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_DISTORTION,            // 19
46       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_LENGTH,                // 20 only for edge
47       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_RADIUS_RATIO        // 21 tet
48       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_ASPECT_BETA      // 22 tet (very similar to 21)
49       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_ASPECT_RATIO   // 23 tet
50       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_ASPECT_GAMMA // 24 tet
51       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_MINIMUM_ANGLE // 25 tet
52       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_COLLAPSE_RATIO // 26 tet
53       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_WARPAGE     // 27 quad
54       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_AREA     // 28 quad
55       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  MB_MAXIMUM_ANGLE // 29 quad
56       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
57       |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
58     */
59     /*0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29*/
60      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},           //  MBVERTEX
61      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},           //  MBEDGE
62      {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1},           //  MBTRI
63      {1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1},           //  MBQUAD
64      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},           //  MBPOLYGON
65      {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0},           //  MBTET
66      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},           //  MBPYRAMID
67      {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},           //  MBPRISM
68      {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},           //  MBKNIFE
69      {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},           // MBHEX
70      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},           //  MBPOLYHEDRON
71      {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}            //  MBENTITYSET
72 };
73 
74 static int numQualities[MBMAXTYPE] =
75 {
76    0, // "MBVERTEX"
77    1, // "MBEDGE", /**< Mesh Edge */
78    13, // "MBTRI", /**< Triangular element (including shells) */
79    22, // "MBQUAD", /**< Quadrilateral element (including shells) */
80    0, // "MBPOLYGON", /**< Polygon */
81    14, // "MBTET", /**< Tetrahedral element */
82    0, //"MBPYRAMID", /**< Pyramid element (where are the face ids for this defined?) */
83    1, // "MBPRISM", /**< Wedge element (Exodus has one, Cubit doesn't. Does Mesh need it?) */
84    1, // "MBKNIFE", /**< Knife element */
85    20,// "MBHEX", /**< Hexahedral element */
86    0, //"MBPOLYHEDRON", /**< Polyhedron */
87    0, // "MBENTITYSET", /**< MeshSet */
88 };
89 static char const * nameQuality [MB_QUALITY_COUNT] =
90 {
91    " edge ratio",          //  MB_EDGE_RATIO = 0,  // 0
92    " maximum edge ratio",  //  MB_MAX_EDGE_RATIO , // 1
93    " skew",                //  MB_SKEW,            // 2
94    " taper" ,              //   MB_TAPER,            // 3
95    " volume" ,             //   MB_VOLUME,          // 4
96    " stretch" ,            //   MB_STRETCH,         // 5
97    " diagonal" ,           //   MB_DIAGONAL,        // 6
98    " characteristic length",           //  MB_DIMENSION,       // 7
99    " oddy" ,               //   MB_ODDY,            // 8
100    " average Frobenius aspect", //  MB_MED_ASPECT_FROBENIUS,// 9
101    " maximum Frobenius aspect", //   MB_MAX_ASPECT_FROBENIUS, // 10
102    " condition number" ,   //   MB_CONDITION,       // 11
103    " jacobian" ,           //   MB_JACOBIAN,        // 12
104    " scaled jacobian" ,    //   MB_SCALED_JACOBIAN, // 13
105    " shear" ,              //   MB_SHEAR,           // 14
106    " shape" ,              //  MB_SHAPE,           // 15
107    " relative size squared",//    MB_RELATIVE_SIZE_SQUARED, // 16
108    " shape and size" ,      //   MB_SHAPE_AND_SIZE,        // 17
109    " shear and size" ,      //   MB_SHEAR_AND_SIZE,        // 18
110    " distortion" ,          //   MB_DISTORTION,            // 19
111       // next are QuadMetricVals that are not in hex metrics
112       // length for edge:
113    " length"  ,             //   MB_LENGTH,                // 20 only for edge
114    " radius ratio",         //   MB_RADIUS_RATIO           // 21 tet
115    " aspect beta",          // MB_ASPECT_BETA              // 22 tet
116    " aspect ratio",         // MB_ASPECT_RATIO,            // 23 MBTET
117    " aspect gamma",         // MB_ASPECT_GAMMA             // 24 tet
118    " minimum angle",        //  MB_MINIMUM_ANGLE,         // 25  MBTET
119    " collapse ratio",        // MB_COLLAPSE_RATIO,        // 26  MBTET
120    " warpage",               // MB_WARPAGE                // 27  MBQUAD
121    " area",                   // MB_AREA                   // 28  MBQAD
122    " maximum angle"          // MB_MAXIMUM_ANGLE          // 29  MBQUAD
123 };
124 
125 static const char * nameType[MBMAXTYPE] =
126 {
127     "MBVERTEX", /**< Mesh Vertex AKA node */
128     "MBEDGE", /**< Mesh Edge */
129     "MBTRI", /**< Triangular element (including shells) */
130     "MBQUAD", /**< Quadrilateral element (including shells) */
131     "MBPOLYGON", /**< Polygon */
132     "MBTET", /**< Tetrahedral element */
133     "MBPYRAMID", /**< Pyramid element (where are the face ids for this defined?) */
134     "MBPRISM", /**< Wedge element (Exodus has one, Cubit doesn't. Does Mesh need it?) */
135     "MBKNIFE", /**< Knife element */
136     "MBHEX", /**< Hexahedral element */
137     "MBPOLYHEDRON", /**< Polyhedron */
138     "MBENTITYSET", /**< MeshSet */
139 };
140 
quality_measure(EntityHandle eh,QualityType q,double & quality,int num_nodes,EntityType etype,double * coords)141 ErrorCode VerdictWrapper::quality_measure(EntityHandle eh, QualityType q, double & quality,
142     int num_nodes, EntityType etype, double * coords)
143 {
144   double coordinates[27][3]; // at most 27 nodes per element
145 
146   if (0==num_nodes && NULL==coords)
147   {
148     etype= TYPE_FROM_HANDLE(eh);
149     if (possibleQuality[etype][q]==0)
150       return MB_NOT_IMPLEMENTED;
151 
152     // get coordinates of points, if not passed already
153     const EntityHandle * conn = NULL;
154     //int num_nodes;
155     ErrorCode rval = mbImpl->get_connectivity(eh, conn, num_nodes);
156     if (rval!=MB_SUCCESS)
157       return rval;
158     if (etype!=MBPOLYHEDRON)
159     {
160       rval = mbImpl->get_coords(conn, num_nodes, &(coordinates[0][0]));
161       if (rval!=MB_SUCCESS)
162         return rval;
163     }
164   }
165   else
166   {
167     if (num_nodes > 27)
168       return MB_FAILURE;
169     for (int i=0; i<num_nodes; i++)
170     {
171       for (int j=0; j<3; j++)
172         coordinates[i][j]=coords[3*i+j];
173     }
174   }
175   VerdictFunction func=0;
176 
177   switch(etype){
178   case MBHEX:
179   {
180     num_nodes = 8;
181     switch(q) {
182     case MB_EDGE_RATIO:           func = v_hex_edge_ratio; break;          // 0
183     case MB_MAX_EDGE_RATIO:       func = v_hex_max_edge_ratio; break;      // 1
184     case MB_SKEW:                 func = v_hex_skew; break;                // 2
185     case MB_TAPER:                func = v_hex_taper; break;               // 3
186     case MB_VOLUME:               func = v_hex_volume; break;              // 4
187     case MB_STRETCH:              func = v_hex_stretch; break;             // 5
188     case MB_DIAGONAL:             func = v_hex_diagonal; break;            // 6
189     case MB_DIMENSION:            func = v_hex_dimension; break;           // 7
190     case MB_ODDY:                 func = v_hex_oddy; break;                // 8
191     case MB_MED_ASPECT_FROBENIUS: func = v_hex_med_aspect_frobenius; break;// 9
192     case MB_MAX_ASPECT_FROBENIUS: func = v_hex_max_aspect_frobenius; break;// 10
193     case MB_CONDITION:            func = v_hex_condition; break;           // 11
194     case MB_JACOBIAN:             func = v_hex_jacobian; break;            // 12
195     case MB_SCALED_JACOBIAN:      func = v_hex_scaled_jacobian; break;     // 13
196     case MB_SHEAR:                func = v_hex_shear; break;               // 14
197     case MB_SHAPE:                func = v_hex_shape; break;               // 15
198     case MB_RELATIVE_SIZE_SQUARED:func = v_hex_relative_size_squared; break; // 16
199     case MB_SHAPE_AND_SIZE:       func = v_hex_shape_and_size; break  ;      // 17
200     case MB_SHEAR_AND_SIZE:       func = v_hex_shear_and_size; break;        // 18
201     case MB_DISTORTION:           func = v_hex_distortion; break;            // 19
202     default :  return MB_FAILURE;
203     }
204     break;
205   }
206   case MBEDGE:
207   {
208     num_nodes = 2;
209     switch (q) {
210     case MB_LENGTH: func = v_edge_length; break;                             // 20
211     default : return MB_FAILURE;
212     }
213     break;
214   }
215   case MBTET:
216   {
217     num_nodes = 4;
218     switch (q) {
219     case MB_EDGE_RATIO:           func = v_tet_edge_ratio; break;           // 0 //! Calculates tet edge ratio metric.
220     case MB_RADIUS_RATIO:         func = v_tet_radius_ratio; break;         // 21
221     case MB_ASPECT_BETA:          func = v_tet_aspect_beta; break;          // 22
222     case MB_ASPECT_RATIO:         func = v_tet_aspect_ratio; break;         // 23
223     case MB_ASPECT_GAMMA:         func = v_tet_aspect_gamma; break;         // 24
224     case MB_MAX_ASPECT_FROBENIUS: func = v_tet_aspect_frobenius; break;     // 10
225     case MB_MINIMUM_ANGLE:        func = v_tet_minimum_angle; break;        // 25
226     case MB_COLLAPSE_RATIO:       func = v_tet_collapse_ratio; break;       // 26
227     case MB_VOLUME:               func = v_tet_volume; break;               // 4
228     case MB_CONDITION:            func = v_tet_condition; break;            // 11
229     case MB_JACOBIAN:             func = v_tet_jacobian; break;             // 12
230     case MB_SCALED_JACOBIAN:      func = v_tet_scaled_jacobian; break;      // 13
231     case MB_SHAPE:                func = v_tet_shape; break;                // 15
232     case MB_RELATIVE_SIZE_SQUARED:func = v_tet_relative_size_squared; break;// 16
233     case MB_SHAPE_AND_SIZE:       func = v_tet_shape_and_size; break;       // 17
234     case MB_DISTORTION:           func = v_tet_distortion; break;           // 19
235     default : return MB_FAILURE;
236     }
237     break;
238   }
239   case MBPRISM:
240   {
241     num_nodes = 6;
242     switch (q) {
243     case MB_VOLUME:               func = v_wedge_volume;    break;          // 4
244     default : return MB_FAILURE;
245     }
246     break;
247   }
248   case MBKNIFE:
249   {
250     num_nodes = 7;
251     switch (q) {
252     case MB_VOLUME:               func = v_knife_volume;    break;          // 4
253     default : return MB_FAILURE;
254     }
255     break;
256   }
257   case MBQUAD:
258   {
259     num_nodes = 4;
260     switch (q) {
261     case MB_EDGE_RATIO:           func = v_quad_edge_ratio; break;          // 0
262     case MB_MAX_EDGE_RATIO:       func = v_quad_max_edge_ratio; break;      // 1
263     case MB_ASPECT_RATIO:         func = v_quad_aspect_ratio; break;        // 23
264     case MB_RADIUS_RATIO:         func = v_quad_radius_ratio; break;        // 21
265     case MB_MED_ASPECT_FROBENIUS: func = v_quad_med_aspect_frobenius; break;// 9
266     case MB_MAX_ASPECT_FROBENIUS: func = v_quad_max_aspect_frobenius; break;//10
267     case MB_SKEW:                 func = v_quad_skew; break;                // 2
268     case MB_TAPER:                func = v_quad_taper; break;               // 3
269     case MB_WARPAGE:              func = v_quad_warpage; break;             // 27
270     case MB_AREA:                 func = v_quad_area; break;                // 28
271     case MB_STRETCH:              func = v_quad_stretch; break;             // 5
272     case MB_MINIMUM_ANGLE:        func = v_quad_minimum_angle; break;       // 25
273     case MB_MAXIMUM_ANGLE:        func = v_quad_maximum_angle; break;       // 29
274     case MB_ODDY:                 func = v_quad_oddy; break;                // 8
275     case MB_CONDITION:            func = v_quad_condition; break;           // 11
276     case MB_JACOBIAN:             func = v_quad_jacobian; break;            // 12
277     case MB_SCALED_JACOBIAN:      func = v_quad_scaled_jacobian; break;     // 13
278     case MB_SHEAR:                func = v_quad_shear; break;               // 14
279     case MB_SHAPE:                func = v_quad_shape; break;               // 15
280     case MB_RELATIVE_SIZE_SQUARED:func = v_quad_relative_size_squared; break; // 16
281     case MB_SHAPE_AND_SIZE:       func = v_quad_shape_and_size; break  ;      // 17
282     case MB_SHEAR_AND_SIZE:       func = v_quad_shear_and_size; break;        // 18
283     case MB_DISTORTION:           func = v_quad_distortion; break;            // 19
284     default :  return MB_FAILURE;
285     }
286     break;
287   }
288 
289   case MBTRI:
290   {
291     num_nodes = 3;
292     switch(q) {
293     case MB_EDGE_RATIO:           func = v_tri_edge_ratio; break;             // 0
294     case MB_ASPECT_RATIO:         func = v_tri_aspect_ratio; break;           // 23
295     case MB_RADIUS_RATIO:         func = v_tri_radius_ratio; break;           // 21
296     case MB_MAX_ASPECT_FROBENIUS: func = v_tri_aspect_frobenius; break;       // 10
297     case MB_AREA:                 func = v_tri_area; break;                   // 28
298     case MB_MINIMUM_ANGLE:        func = v_tri_minimum_angle; break;          // 25
299     case MB_MAXIMUM_ANGLE:        func = v_tri_maximum_angle; break;          // 29
300     case MB_CONDITION:            func = v_tri_condition; break;              // 11
301     case MB_SCALED_JACOBIAN:      func = v_tri_scaled_jacobian; break;        // 13
302     // does not exist, even though it was defined in verdict.h; remove it from there too
303     // case MB_SHEAR:                func = v_tri_shear; break;                  // 14
304     case MB_RELATIVE_SIZE_SQUARED:func = v_tri_relative_size_squared; break;  // 16
305     case MB_SHAPE:                func = v_tri_shape; break;                  // 15
306     case MB_SHAPE_AND_SIZE:       func = v_tri_shape_and_size; break  ;       // 17
307     case MB_DISTORTION:           func = v_tri_distortion; break;             // 19
308     default :  return MB_FAILURE;
309     }
310     break;
311   }
312   default : break; // some have no measures
313   }
314 
315   if (!func)
316     return MB_NOT_IMPLEMENTED;
317   // actual computation happens here
318   quality = (*func)(num_nodes, coordinates);
319 
320   return MB_SUCCESS;
321 }
quality_name(QualityType q)322 const char * VerdictWrapper::quality_name (QualityType q)
323 {
324   return nameQuality[q];
325 }
entity_type_name(EntityType etype)326 const char * VerdictWrapper::entity_type_name(EntityType etype)
327 {
328   return nameType[etype];
329 }
num_qualities(EntityType etype)330 int VerdictWrapper::num_qualities(EntityType etype)
331 {
332   return numQualities[etype];
333 }
possible_quality(EntityType et,QualityType q)334 int VerdictWrapper::possible_quality(EntityType et, QualityType q)
335 {
336   return possibleQuality[et][q];
337 }
338   // relative size needs a base size, that is set at global level, one for each major type (hex, tet, quad, tri)
set_size(double size)339 ErrorCode VerdictWrapper::set_size(double size)
340 {
341   // set the sizes for all of them; maybe we can set by type, this should be enough for simplicity
342   v_set_hex_size (size);
343   v_set_tet_size (size);
344   v_set_quad_size( size );
345   v_set_tri_size( size );
346   return MB_SUCCESS;
347 }
348 
all_quality_measures(EntityHandle eh,std::map<QualityType,double> & qualities)349 ErrorCode VerdictWrapper::all_quality_measures(EntityHandle eh, std::map<QualityType, double> & qualities)
350 {
351   EntityType etype = TYPE_FROM_HANDLE(eh);
352   if (etype == MBPOLYHEDRON || etype == MBVERTEX || etype == MBENTITYSET)
353     return MB_SUCCESS; // no quality for polyhedron or vertex or set
354 
355   double coordinates[27][3]; // at most 27 nodes per element
356   // get coordinates of points, if not passed already
357   const EntityHandle * conn = NULL;
358   int num_nodes;
359   ErrorCode rval = mbImpl->get_connectivity(eh, conn, num_nodes);
360   if (rval != MB_SUCCESS)
361     return rval;
362   rval = mbImpl->get_coords(conn, num_nodes, &(coordinates[0][0]));
363   if (rval != MB_SUCCESS)
364     return rval;
365 
366   switch (etype) {
367   case MBEDGE: {
368     double leng = v_edge_length(2, coordinates);
369     qualities[MB_LENGTH] = leng;
370     break;
371   }
372   case MBHEX: {
373     num_nodes = 8;
374     HexMetricVals hexMetric;
375     v_hex_quality(num_nodes, coordinates, V_HEX_ALL, &hexMetric);
376     qualities[MB_EDGE_RATIO] = hexMetric.edge_ratio;
377     qualities[MB_MAX_EDGE_RATIO] = hexMetric.max_edge_ratio;
378     qualities[MB_SKEW] = hexMetric.skew;
379     qualities[MB_TAPER] = hexMetric.taper;
380     qualities[MB_VOLUME] = hexMetric.volume;
381     qualities[MB_STRETCH] = hexMetric.stretch;
382     qualities[MB_DIAGONAL] = hexMetric.diagonal;
383     qualities[MB_DIMENSION] = hexMetric.dimension;
384     qualities[MB_ODDY] = hexMetric.oddy;
385     qualities[MB_MED_ASPECT_FROBENIUS] = hexMetric.med_aspect_frobenius;
386     // MB_CONDITION is the same as MB_MAX_ASPECT_FROBENIUS
387     qualities[MB_MAX_ASPECT_FROBENIUS] = hexMetric.condition;
388     qualities[MB_CONDITION] = hexMetric.condition;
389     qualities[MB_JACOBIAN] = hexMetric.jacobian;
390     qualities[MB_SCALED_JACOBIAN] = hexMetric.scaled_jacobian;
391     qualities[MB_SHEAR] = hexMetric.shear;
392     qualities[MB_SHAPE] = hexMetric.shape;
393     qualities[MB_RELATIVE_SIZE_SQUARED] = hexMetric.relative_size_squared;
394     qualities[MB_SHAPE_AND_SIZE] = hexMetric.shape_and_size;
395     qualities[MB_SHEAR_AND_SIZE] = hexMetric.shear_and_size;
396     qualities[MB_DISTORTION] = hexMetric.distortion;
397     break;
398   }
399 
400   case MBTET: {
401     num_nodes = 4;
402     TetMetricVals tetMetrics;
403     v_tet_quality(num_nodes, coordinates, V_TET_ALL, &tetMetrics);
404     qualities[MB_EDGE_RATIO]=tetMetrics.edge_ratio;
405     qualities[MB_RADIUS_RATIO] = tetMetrics.radius_ratio;
406     qualities[MB_ASPECT_BETA] = tetMetrics.aspect_beta;
407     qualities[MB_ASPECT_RATIO] = tetMetrics.aspect_ratio;
408     qualities[MB_ASPECT_GAMMA] = tetMetrics.aspect_gamma;
409     qualities[MB_MAX_ASPECT_FROBENIUS] = tetMetrics.aspect_frobenius;
410     qualities[MB_MINIMUM_ANGLE] = tetMetrics.minimum_angle;
411     qualities[MB_COLLAPSE_RATIO] = tetMetrics.collapse_ratio;
412     qualities[MB_VOLUME] = tetMetrics.volume;
413     qualities[MB_CONDITION] = tetMetrics.condition;
414     qualities[MB_JACOBIAN] = tetMetrics.jacobian;
415     qualities[MB_SCALED_JACOBIAN] = tetMetrics.scaled_jacobian;
416     qualities[MB_SHAPE] = tetMetrics.shape;
417     qualities[MB_RELATIVE_SIZE_SQUARED] = tetMetrics.relative_size_squared;
418     qualities[MB_SHAPE_AND_SIZE] = tetMetrics.shape_and_size;
419     qualities[MB_DISTORTION] = tetMetrics.distortion;
420     break;
421   }
422   case MBPRISM: {
423     num_nodes = 6;
424     double volu = v_wedge_volume(num_nodes, coordinates);
425     qualities[MB_VOLUME] = volu;
426     break;
427   }
428   case MBKNIFE: {
429     num_nodes = 7;
430     double volu = v_knife_volume(num_nodes, coordinates);
431     qualities[MB_VOLUME] = volu;
432     break;
433   }
434   case MBQUAD: {
435     num_nodes = 4;
436     QuadMetricVals quadMetrics;
437     v_quad_quality(num_nodes, coordinates, V_QUAD_ALL, &quadMetrics);
438     qualities[MB_EDGE_RATIO] = quadMetrics.edge_ratio;
439     qualities[MB_MAX_EDGE_RATIO] = quadMetrics.max_edge_ratio;
440     qualities[MB_ASPECT_RATIO] = quadMetrics.aspect_ratio;   // 23
441     qualities[MB_RADIUS_RATIO] = quadMetrics.radius_ratio;     // 21
442     qualities[MB_MED_ASPECT_FROBENIUS] = quadMetrics.med_aspect_frobenius; // 9
443     qualities[MB_MAX_ASPECT_FROBENIUS] = quadMetrics.max_aspect_frobenius; //10
444     qualities[MB_SKEW] = quadMetrics.skew;     // 2
445     qualities[MB_TAPER] = quadMetrics.taper;               // 3
446     qualities[MB_WARPAGE] = quadMetrics.warpage;          // 27
447     qualities[MB_AREA] = quadMetrics.area;           // 28
448     qualities[MB_STRETCH] = quadMetrics.stretch;       // 5
449     qualities[MB_MINIMUM_ANGLE] = quadMetrics.minimum_angle;   // 25
450     qualities[MB_MAXIMUM_ANGLE] = quadMetrics.maximum_angle; // 29
451     qualities[MB_ODDY] = quadMetrics.oddy;          // 8
452     qualities[MB_CONDITION] = quadMetrics.condition;          // 11
453     qualities[MB_JACOBIAN] = quadMetrics.jacobian;        // 12
454     qualities[MB_SCALED_JACOBIAN] = quadMetrics.scaled_jacobian;    // 13
455     qualities[MB_SHEAR] = quadMetrics.shear;     // 14
456     qualities[MB_SHAPE] = quadMetrics.shape;         // 15
457     qualities[MB_RELATIVE_SIZE_SQUARED] = quadMetrics.relative_size_squared; // 16
458     qualities[MB_SHAPE_AND_SIZE] = quadMetrics.shape_and_size;      // 17
459     qualities[MB_SHEAR_AND_SIZE] = quadMetrics.shear_and_size;    // 18
460     qualities[MB_DISTORTION] = quadMetrics.distortion;      // 19
461     break;
462   }
463 
464   case MBTRI: {
465     num_nodes = 3;
466     TriMetricVals triMetrics;
467     v_tri_quality(num_nodes, coordinates, V_TRI_ALL, &triMetrics);
468     qualities[MB_EDGE_RATIO] = triMetrics.edge_ratio;        // 0
469     qualities[MB_ASPECT_RATIO] = triMetrics.aspect_ratio;         // 23
470     qualities[MB_RADIUS_RATIO] = triMetrics.radius_ratio;       // 21
471     qualities[MB_MAX_ASPECT_FROBENIUS] = triMetrics.aspect_frobenius;    // 10
472     qualities[MB_AREA] = triMetrics.area;             // 28
473     qualities[MB_MINIMUM_ANGLE] = triMetrics.minimum_angle;       // 25
474     qualities[MB_MAXIMUM_ANGLE] = triMetrics.maximum_angle;    // 29
475     qualities[MB_CONDITION] = triMetrics.condition;     // 11
476     qualities[MB_SCALED_JACOBIAN] = triMetrics.scaled_jacobian;    // 13
477     // does not exist, even though it was defined in verdict.h; remove it from there too
478     // case MB_SHEAR:                func = v_tri_shear; break;                  // 14
479     qualities[MB_RELATIVE_SIZE_SQUARED] = triMetrics.relative_size_squared; // 16
480     qualities[MB_SHAPE] = triMetrics.shape;           // 15
481     qualities[MB_SHAPE_AND_SIZE] = triMetrics.shape_and_size;     // 17
482     qualities[MB_DISTORTION] = triMetrics.distortion;          // 19
483     break;
484   }
485   default:
486     return MB_NOT_IMPLEMENTED;
487   }
488   return MB_SUCCESS;
489 }
490 
491 } // end namespace
492