MOAB: Mesh Oriented datABase  (version 5.3.1)
LinearQuadrilateral.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines