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 }