Mesh Oriented datABase  (version 5.5.1)
An array-based unstructured mesh library
V_PyramidMetric.cpp
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Module: $RCSfile: V_PyramidMetric.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  * PyramidMetrics.cpp contains quality calculations for Pyramids
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 /*
30  the pyramid element
31 
32  5
33  ^
34  |\
35  /| \\_
36  | \ \
37  | | \_ \_
38  / \/4\ \
39  | /| \ \_
40  | / \ \ \
41  / | \
42  1 \_ | _/3
43  \_ \ _/
44  \_ | _/
45  \_/
46  2
47 
48  a quadrilateral base and a pointy peak like a pyramid
49 
50 */
51 
52 /*!
53  the volume of a pyramid
54 
55  the volume is calculated by dividing the pyramid into
56  2 tets and summing the volumes of the 2 tets.
57 */
58 
59 C_FUNC_DEF double v_pyramid_volume( int num_nodes, double coordinates[][3] )
60 {
61 
62  double volume = 0;
63  VerdictVector side1, side2, side3;
64 
65  if( num_nodes == 5 )
66  {
67  // divide the pyramid into 2 tets and calculate each
68 
69  side1.set( coordinates[1][0] - coordinates[0][0], coordinates[1][1] - coordinates[0][1],
70  coordinates[1][2] - coordinates[0][2] );
71 
72  side2.set( coordinates[3][0] - coordinates[0][0], coordinates[3][1] - coordinates[0][1],
73  coordinates[3][2] - coordinates[0][2] );
74 
75  side3.set( coordinates[4][0] - coordinates[0][0], coordinates[4][1] - coordinates[0][1],
76  coordinates[4][2] - coordinates[0][2] );
77 
78  // volume of the first tet
79  volume = ( side3 % ( side1 * side2 ) ) / 6.0;
80 
81  side1.set( coordinates[3][0] - coordinates[2][0], coordinates[3][1] - coordinates[2][1],
82  coordinates[3][2] - coordinates[2][2] );
83 
84  side2.set( coordinates[1][0] - coordinates[2][0], coordinates[1][1] - coordinates[2][1],
85  coordinates[1][2] - coordinates[2][2] );
86 
87  side3.set( coordinates[4][0] - coordinates[2][0], coordinates[4][1] - coordinates[2][1],
88  coordinates[4][2] - coordinates[2][2] );
89 
90  // volume of the second tet
91  volume += ( side3 % ( side1 * side2 ) ) / 6.0;
92  }
93  return (double)volume;
94 }
95 
96 C_FUNC_DEF void v_pyramid_quality( int num_nodes,
97  double coordinates[][3],
98  unsigned int metrics_request_flag,
99  PyramidMetricVals* metric_vals )
100 {
101  memset( metric_vals, 0, sizeof( PyramidMetricVals ) );
102 
103  if( metrics_request_flag & V_PYRAMID_VOLUME ) metric_vals->volume = v_pyramid_volume( num_nodes, coordinates );
104 }