MOAB: Mesh Oriented datABase
(version 5.3.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2006 Lawrence Livermore National Laboratory. Under 00005 the terms of Contract B545069 with the University of Wisconsin -- 00006 Madison, Lawrence Livermore National Laboratory retains certain 00007 rights in this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 (2006) kraftche@cae.wisc.edu 00024 00025 ***************************************************************** */ 00026 /** \file LinearQuadrilateral.cpp 00027 * \author Jason Kraftcheck 00028 */ 00029 00030 #include "Mesquite.hpp" 00031 #include "MsqError.hpp" 00032 #include "LinearQuadrilateral.hpp" 00033 00034 namespace MBMesquite 00035 { 00036 00037 static const char* nonlinear_error = "Attempt to use LinearQuadrilateral mapping function for a nonlinear element\n"; 00038 00039 EntityTopology LinearQuadrilateral::element_topology() const 00040 { 00041 return QUADRILATERAL; 00042 } 00043 00044 int LinearQuadrilateral::num_nodes() const 00045 { 00046 return 4; 00047 } 00048 00049 void LinearQuadrilateral::coefficients( Sample location, NodeSet nodeset, double* coeff_out, size_t* indices_out, 00050 size_t& num_coeff, MsqError& err ) const 00051 { 00052 if( nodeset.have_any_mid_node() ) 00053 { 00054 MSQ_SETERR( err )( nonlinear_error, MsqError::UNSUPPORTED_ELEMENT ); 00055 return; 00056 } 00057 00058 coefficients( location, nodeset, coeff_out, indices_out, num_coeff ); 00059 } 00060 00061 void LinearQuadrilateral::coefficients( Sample location, NodeSet, double* coeff_out, size_t* indices_out, 00062 size_t& num_coeff ) 00063 { 00064 switch( location.dimension ) 00065 { 00066 case 0: 00067 num_coeff = 1; 00068 indices_out[0] = location.number; 00069 coeff_out[0] = 1.0; 00070 break; 00071 case 1: 00072 num_coeff = 2; 00073 indices_out[0] = location.number; 00074 indices_out[1] = ( location.number + 1 ) % 4; 00075 coeff_out[0] = 0.5; 00076 coeff_out[1] = 0.5; 00077 break; 00078 case 2: 00079 num_coeff = 4; 00080 indices_out[0] = 0; 00081 indices_out[1] = 1; 00082 indices_out[2] = 2; 00083 indices_out[3] = 3; 00084 coeff_out[0] = 0.25; 00085 coeff_out[1] = 0.25; 00086 coeff_out[2] = 0.25; 00087 coeff_out[3] = 0.25; 00088 break; 00089 default: 00090 num_coeff = 0; 00091 } 00092 } 00093 00094 const unsigned xi = 0; 00095 const unsigned eta = 1; 00096 const int sign[2][4] = { { -1, 1, 1, -1 }, // xi 00097 { -1, -1, 1, 1 } }; // eta 00098 00099 static void derivatives_at_corner( unsigned corner, size_t* vertex_indices, MsqVector< 2 >* derivs, size_t& num_vtx ) 00100 { 00101 const unsigned adj_in_xi = ( 5 - corner ) % 4; 00102 const unsigned adj_in_eta = 3 - corner; 00103 00104 num_vtx = 3; 00105 vertex_indices[0] = corner; 00106 vertex_indices[1] = adj_in_xi; 00107 vertex_indices[2] = adj_in_eta; 00108 00109 derivs[0][0] = sign[xi][corner]; 00110 derivs[0][1] = sign[eta][corner]; 00111 derivs[1][0] = sign[xi][adj_in_xi]; 00112 derivs[1][1] = 0.0; 00113 derivs[2][0] = 0.0; 00114 derivs[2][1] = sign[eta][adj_in_eta]; 00115 } 00116 00117 static void derivatives_at_mid_edge( unsigned edge, size_t* vertices, MsqVector< 2 >* derivs, size_t& num_vtx ) 00118 { 00119 const unsigned start_vtx = edge; 00120 const unsigned end_vtx = ( edge + 1 ) % 4; 00121 const unsigned othr1_vtx = ( edge + 2 ) % 4; 00122 const unsigned othr2_vtx = ( edge + 3 ) % 4; 00123 const unsigned direction = edge % 2; 00124 const unsigned orthogonal = 1 - direction; 00125 00126 num_vtx = 4; 00127 vertices[0] = 0; 00128 vertices[1] = 1; 00129 vertices[2] = 2; 00130 vertices[3] = 3; 00131 00132 derivs[start_vtx][direction] = sign[direction][start_vtx]; 00133 derivs[end_vtx][direction] = sign[direction][end_vtx]; 00134 derivs[othr1_vtx][direction] = 0.0; 00135 derivs[othr2_vtx][direction] = 0.0; 00136 00137 derivs[0][orthogonal] = 0.5 * sign[orthogonal][0]; 00138 derivs[1][orthogonal] = 0.5 * sign[orthogonal][1]; 00139 derivs[2][orthogonal] = 0.5 * sign[orthogonal][2]; 00140 derivs[3][orthogonal] = 0.5 * sign[orthogonal][3]; 00141 } 00142 00143 static void derivatives_at_mid_elem( size_t* vertices, MsqVector< 2 >* derivs, size_t& num_vtx ) 00144 { 00145 num_vtx = 4; 00146 vertices[0] = 0; 00147 derivs[0][0] = -0.5; 00148 derivs[0][1] = -0.5; 00149 vertices[1] = 1; 00150 derivs[1][0] = 0.5; 00151 derivs[1][1] = -0.5; 00152 vertices[2] = 2; 00153 derivs[2][0] = 0.5; 00154 derivs[2][1] = 0.5; 00155 vertices[3] = 3; 00156 derivs[3][0] = -0.5; 00157 derivs[3][1] = 0.5; 00158 } 00159 00160 void LinearQuadrilateral::derivatives( Sample loc, NodeSet nodeset, size_t* vertex_indices_out, 00161 MsqVector< 2 >* d_coeff_d_xi_out, size_t& num_vtx, MsqError& err ) const 00162 { 00163 if( nodeset.have_any_mid_node() ) 00164 { 00165 MSQ_SETERR( err )( nonlinear_error, MsqError::UNSUPPORTED_ELEMENT ); 00166 return; 00167 } 00168 00169 derivatives( loc, nodeset, vertex_indices_out, d_coeff_d_xi_out, num_vtx ); 00170 } 00171 00172 void LinearQuadrilateral::derivatives( Sample loc, NodeSet, size_t* vertex_indices_out, 00173 MsqVector< 2 >* d_coeff_d_xi_out, size_t& num_vtx ) 00174 { 00175 switch( loc.dimension ) 00176 { 00177 case 0: 00178 derivatives_at_corner( loc.number, vertex_indices_out, d_coeff_d_xi_out, num_vtx ); 00179 break; 00180 case 1: 00181 derivatives_at_mid_edge( loc.number, vertex_indices_out, d_coeff_d_xi_out, num_vtx ); 00182 break; 00183 case 2: 00184 derivatives_at_mid_elem( vertex_indices_out, d_coeff_d_xi_out, num_vtx ); 00185 break; 00186 default: 00187 num_vtx = 0; 00188 } 00189 } 00190 00191 void LinearQuadrilateral::ideal( Sample, MsqMatrix< 3, 2 >& J, MsqError& ) const 00192 { 00193 J( 0, 0 ) = J( 1, 1 ) = 1.0; 00194 J( 0, 1 ) = J( 1, 0 ) = 0.0; 00195 J( 2, 0 ) = J( 2, 1 ) = 0.0; 00196 } 00197 00198 } // namespace MBMesquite