Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
V_KnifeMetric.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Module: $RCSfile: V_KnifeMetric.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  * KnifeMetrics.cpp contains quality calculations for knives
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 <memory.h>
28 
29 /* a knife element
30 
31  3
32  _/\_
33  _/ | \_
34  0 _/ \_ 2
35  |\_ | ___/|
36  | \ __/ |
37  | 1\/ | |
38  | \ |
39  |_____\|_____|
40  4 5 6
41 
42 
43  (edge 3,5 is is a hidden line if you will)
44 
45  if this is hard to visualize, consider a hex
46  with nodes 5 and 7 becoming the same node
47 
48 
49 */
50 
51 /*!
52  calculates the volume of a knife element
53 
54  this is done by dividing the knife into 4 tets
55  and summing the volumes of each.
56 */
57 
58 C_FUNC_DEF double v_knife_volume( int num_nodes, double coordinates[][3] )
59 {
60  double volume = 0;
61  VerdictVector side1, side2, side3;
62 
63  if( num_nodes == 7 )
64  {
65 
66  // divide the knife into 4 tets and calculate the volume
67 
68  side1.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
69  coordinates[1][2] - coordinates[0][2] );
70  side2.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
71  coordinates[3][2] - coordinates[0][2] );
72  side3.set( coordinates[4][0] - coordinates[0][0], coordinates[4][1] - coordinates[0][1],
73  coordinates[4][2] - coordinates[0][2] );
74 
75  volume = side3 % ( side1 * side2 ) / 6;
76 
77  side1.set( coordinates[5][0] - coordinates[1][0], coordinates[5][1] - coordinates[1][1],
78  coordinates[5][2] - coordinates[1][2] );
79  side2.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
80  coordinates[3][2] - coordinates[1][2] );
81  side3.set( coordinates[4][0] - coordinates[1][0], coordinates[4][1] - coordinates[1][1],
82  coordinates[4][2] - coordinates[1][2] );
83 
84  volume += side3 % ( side1 * side2 ) / 6;
85 
86  side1.set( coordinates[2][0] - coordinates[1][0], coordinates[2][1] - coordinates[1][1],
87  coordinates[2][2] - coordinates[1][2] );
88  side2.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
89  coordinates[3][2] - coordinates[1][2] );
90  side3.set( coordinates[6][0] - coordinates[1][0], coordinates[6][1] - coordinates[1][1],
91  coordinates[6][2] - coordinates[1][2] );
92 
93  volume += side3 % ( side1 * side2 ) / 6;
94 
95  side1.set( coordinates[3][0] - coordinates[1][0], coordinates[3][1] - coordinates[1][1],
96  coordinates[3][2] - coordinates[1][2] );
97  side2.set( coordinates[5][0] - coordinates[1][0], coordinates[5][1] - coordinates[1][1],
98  coordinates[5][2] - coordinates[1][2] );
99  side3.set( coordinates[6][0] - coordinates[1][0], coordinates[6][1] - coordinates[1][1],
100  coordinates[6][2] - coordinates[1][2] );
101 
102  volume += side3 % ( side1 * side2 ) / 6;
103  }
104 
105  return (double)volume;
106 }
107 
108 /*!
109 
110  calculate the quality metrics of a knife element.
111 
112  There is only one, but we put this here to be consistent with
113  functions for other element types. Who knows if we'll add
114  more metrics.
115 */
116 
117 C_FUNC_DEF void v_knife_quality( int num_nodes,
118  double coordinates[][3],
119  unsigned int metrics_request_flag,
120  KnifeMetricVals* metric_vals )
121 {
122  memset( metric_vals, 0, sizeof( KnifeMetricVals ) );
123 
124  if( metrics_request_flag & V_KNIFE_VOLUME ) metric_vals->volume = v_knife_volume( num_nodes, coordinates );
125 }