Branch data Line data Source code
1 : : /* *****************************************************************
2 : : MESQUITE -- The Mesh Quality Improvement Toolkit
3 : :
4 : : Copyright 2006 Lawrence Livermore National Laboratory. Under
5 : : the terms of Contract B545069 with the University of Wisconsin --
6 : : Madison, Lawrence Livermore National Laboratory retains certain
7 : : rights in this software.
8 : :
9 : : This library is free software; you can redistribute it and/or
10 : : modify it under the terms of the GNU Lesser General Public
11 : : License as published by the Free Software Foundation; either
12 : : version 2.1 of the License, or (at your option) any later version.
13 : :
14 : : This library is distributed in the hope that it will be useful,
15 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : Lesser General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU Lesser General Public License
20 : : (lgpl.txt) along with this library; if not, write to the Free Software
21 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 : :
23 : : (2006) [email protected]
24 : :
25 : : ***************************************************************** */
26 : : /** \file LinearQuadrilateral.cpp
27 : : * \author Jason Kraftcheck
28 : : */
29 : :
30 : : #include "Mesquite.hpp"
31 : : #include "MsqError.hpp"
32 : : #include "LinearQuadrilateral.hpp"
33 : :
34 : : namespace MBMesquite
35 : : {
36 : :
37 : : static const char* nonlinear_error = "Attempt to use LinearQuadrilateral mapping function for a nonlinear element\n";
38 : :
39 : 0 : EntityTopology LinearQuadrilateral::element_topology() const
40 : : {
41 : 0 : return QUADRILATERAL;
42 : : }
43 : :
44 : 0 : int LinearQuadrilateral::num_nodes() const
45 : : {
46 : 0 : return 4;
47 : : }
48 : :
49 : 0 : void LinearQuadrilateral::coefficients( Sample location, NodeSet nodeset, double* coeff_out, size_t* indices_out,
50 : : size_t& num_coeff, MsqError& err ) const
51 : : {
52 [ # # ]: 0 : if( nodeset.have_any_mid_node() )
53 : : {
54 [ # # ]: 0 : MSQ_SETERR( err )( nonlinear_error, MsqError::UNSUPPORTED_ELEMENT );
55 : 0 : return;
56 : : }
57 : :
58 : 0 : coefficients( location, nodeset, coeff_out, indices_out, num_coeff );
59 : : }
60 : :
61 : 708 : void LinearQuadrilateral::coefficients( Sample location, NodeSet, double* coeff_out, size_t* indices_out,
62 : : size_t& num_coeff )
63 : : {
64 [ - + - - ]: 708 : switch( location.dimension )
65 : : {
66 : : case 0:
67 : 0 : num_coeff = 1;
68 : 0 : indices_out[0] = location.number;
69 : 0 : coeff_out[0] = 1.0;
70 : 0 : break;
71 : : case 1:
72 : 708 : num_coeff = 2;
73 : 708 : indices_out[0] = location.number;
74 : 708 : indices_out[1] = ( location.number + 1 ) % 4;
75 : 708 : coeff_out[0] = 0.5;
76 : 708 : coeff_out[1] = 0.5;
77 : 708 : break;
78 : : case 2:
79 : 0 : num_coeff = 4;
80 : 0 : indices_out[0] = 0;
81 : 0 : indices_out[1] = 1;
82 : 0 : indices_out[2] = 2;
83 : 0 : indices_out[3] = 3;
84 : 0 : coeff_out[0] = 0.25;
85 : 0 : coeff_out[1] = 0.25;
86 : 0 : coeff_out[2] = 0.25;
87 : 0 : coeff_out[3] = 0.25;
88 : 0 : break;
89 : : default:
90 : 0 : num_coeff = 0;
91 : : }
92 : 708 : }
93 : :
94 : : const unsigned xi = 0;
95 : : const unsigned eta = 1;
96 : : const int sign[2][4] = { { -1, 1, 1, -1 }, // xi
97 : : { -1, -1, 1, 1 } }; // eta
98 : :
99 : 19373822 : static void derivatives_at_corner( unsigned corner, size_t* vertex_indices, MsqVector< 2 >* derivs, size_t& num_vtx )
100 : : {
101 : 19373822 : const unsigned adj_in_xi = ( 5 - corner ) % 4;
102 : 19373822 : const unsigned adj_in_eta = 3 - corner;
103 : :
104 : 19373822 : num_vtx = 3;
105 : 19373822 : vertex_indices[0] = corner;
106 : 19373822 : vertex_indices[1] = adj_in_xi;
107 : 19373822 : vertex_indices[2] = adj_in_eta;
108 : :
109 : 19373822 : derivs[0][0] = sign[xi][corner];
110 : 19373822 : derivs[0][1] = sign[eta][corner];
111 : 19373822 : derivs[1][0] = sign[xi][adj_in_xi];
112 : 19373822 : derivs[1][1] = 0.0;
113 : 19373822 : derivs[2][0] = 0.0;
114 : 19373822 : derivs[2][1] = sign[eta][adj_in_eta];
115 : 19373822 : }
116 : :
117 : 0 : static void derivatives_at_mid_edge( unsigned edge, size_t* vertices, MsqVector< 2 >* derivs, size_t& num_vtx )
118 : : {
119 : 0 : const unsigned start_vtx = edge;
120 : 0 : const unsigned end_vtx = ( edge + 1 ) % 4;
121 : 0 : const unsigned othr1_vtx = ( edge + 2 ) % 4;
122 : 0 : const unsigned othr2_vtx = ( edge + 3 ) % 4;
123 : 0 : const unsigned direction = edge % 2;
124 : 0 : const unsigned orthogonal = 1 - direction;
125 : :
126 : 0 : num_vtx = 4;
127 : 0 : vertices[0] = 0;
128 : 0 : vertices[1] = 1;
129 : 0 : vertices[2] = 2;
130 : 0 : vertices[3] = 3;
131 : :
132 : 0 : derivs[start_vtx][direction] = sign[direction][start_vtx];
133 : 0 : derivs[end_vtx][direction] = sign[direction][end_vtx];
134 : 0 : derivs[othr1_vtx][direction] = 0.0;
135 : 0 : derivs[othr2_vtx][direction] = 0.0;
136 : :
137 : 0 : derivs[0][orthogonal] = 0.5 * sign[orthogonal][0];
138 : 0 : derivs[1][orthogonal] = 0.5 * sign[orthogonal][1];
139 : 0 : derivs[2][orthogonal] = 0.5 * sign[orthogonal][2];
140 : 0 : derivs[3][orthogonal] = 0.5 * sign[orthogonal][3];
141 : 0 : }
142 : :
143 : 0 : static void derivatives_at_mid_elem( size_t* vertices, MsqVector< 2 >* derivs, size_t& num_vtx )
144 : : {
145 : 0 : num_vtx = 4;
146 : 0 : vertices[0] = 0;
147 : 0 : derivs[0][0] = -0.5;
148 : 0 : derivs[0][1] = -0.5;
149 : 0 : vertices[1] = 1;
150 : 0 : derivs[1][0] = 0.5;
151 : 0 : derivs[1][1] = -0.5;
152 : 0 : vertices[2] = 2;
153 : 0 : derivs[2][0] = 0.5;
154 : 0 : derivs[2][1] = 0.5;
155 : 0 : vertices[3] = 3;
156 : 0 : derivs[3][0] = -0.5;
157 : 0 : derivs[3][1] = 0.5;
158 : 0 : }
159 : :
160 : 0 : void LinearQuadrilateral::derivatives( Sample loc, NodeSet nodeset, size_t* vertex_indices_out,
161 : : MsqVector< 2 >* d_coeff_d_xi_out, size_t& num_vtx, MsqError& err ) const
162 : : {
163 [ # # ]: 0 : if( nodeset.have_any_mid_node() )
164 : : {
165 [ # # ]: 0 : MSQ_SETERR( err )( nonlinear_error, MsqError::UNSUPPORTED_ELEMENT );
166 : 0 : return;
167 : : }
168 : :
169 : 0 : derivatives( loc, nodeset, vertex_indices_out, d_coeff_d_xi_out, num_vtx );
170 : : }
171 : :
172 : 19373822 : void LinearQuadrilateral::derivatives( Sample loc, NodeSet, size_t* vertex_indices_out,
173 : : MsqVector< 2 >* d_coeff_d_xi_out, size_t& num_vtx )
174 : : {
175 [ + - - - ]: 19373822 : switch( loc.dimension )
176 : : {
177 : : case 0:
178 : 19373822 : derivatives_at_corner( loc.number, vertex_indices_out, d_coeff_d_xi_out, num_vtx );
179 : 19373822 : break;
180 : : case 1:
181 : 0 : derivatives_at_mid_edge( loc.number, vertex_indices_out, d_coeff_d_xi_out, num_vtx );
182 : 0 : break;
183 : : case 2:
184 : 0 : derivatives_at_mid_elem( vertex_indices_out, d_coeff_d_xi_out, num_vtx );
185 : 0 : break;
186 : : default:
187 : 0 : num_vtx = 0;
188 : : }
189 : 19373822 : }
190 : :
191 : 0 : void LinearQuadrilateral::ideal( Sample, MsqMatrix< 3, 2 >& J, MsqError& ) const
192 : : {
193 : 0 : J( 0, 0 ) = J( 1, 1 ) = 1.0;
194 : 0 : J( 0, 1 ) = J( 1, 0 ) = 0.0;
195 : 0 : J( 2, 0 ) = J( 2, 1 ) = 0.0;
196 : 0 : }
197 : :
198 : : } // namespace MBMesquite
|