MOAB: Mesh Oriented datABase  (version 5.2.1)
IdealTargetTest.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2006 Sandia National Laboratories.  Developed at the
00005     University of Wisconsin--Madison under SNL contract number
00006     624796.  The U.S. Government and the University of Wisconsin
00007     retian certain rights to 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 
00027 /** \file IdealTargetTest.cpp
00028  *  \brief Test the IdealShapeTarget
00029  *  \author Jason Kraftcheck
00030  */
00031 
00032 #include "Mesquite.hpp"
00033 #include "IdealShapeTarget.hpp"
00034 #include "MsqError.hpp"
00035 #include "Vector3D.hpp"
00036 #include "PatchData.hpp"
00037 #include "PlanarDomain.hpp"
00038 #include "MappingFunction.hpp"
00039 #include "Settings.hpp"
00040 #include "IdealElements.hpp"
00041 #include "ElemSampleQM.hpp"
00042 #include "cppunit/extensions/HelperMacros.h"
00043 #include "UnitUtil.hpp"
00044 
00045 using namespace MBMesquite;
00046 
00047 class IdealTargetTest : public CppUnit::TestFixture
00048 {
00049   private:
00050     CPPUNIT_TEST_SUITE( IdealTargetTest );
00051     CPPUNIT_TEST( test_tri_corner );
00052     CPPUNIT_TEST( test_tri_edge );
00053     CPPUNIT_TEST( test_tri_center );
00054     CPPUNIT_TEST( test_hex_corner );
00055     CPPUNIT_TEST( test_hex_edge );
00056     CPPUNIT_TEST( test_hex_face );
00057     CPPUNIT_TEST( test_hex_center );
00058     CPPUNIT_TEST_SUITE_END();
00059 
00060   public:
00061     void test_tri_corner();
00062     void test_tri_edge();
00063     void test_tri_center();
00064     void test_hex_corner();
00065     void test_hex_edge();
00066     void test_hex_face();
00067     void test_hex_center();
00068 
00069   private:
00070     void get_calc_target( EntityTopology type, Sample sample, MsqMatrix< 3, 3 >&, MsqMatrix< 2, 2 >& );
00071 
00072     void get_ideal_target( EntityTopology type, Sample sample, MsqMatrix< 3, 3 >&, MsqMatrix< 2, 2 >& );
00073 
00074     void do_test( EntityTopology type, Sample location );
00075 
00076     Settings settings;
00077 };
00078 
00079 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( IdealTargetTest, "IdealTargetTest" );
00080 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( IdealTargetTest, "Unit" );
00081 
00082 void IdealTargetTest::test_tri_corner()
00083 {
00084     do_test( TRIANGLE, Sample( 0, 0 ) );
00085     do_test( TRIANGLE, Sample( 0, 1 ) );
00086     do_test( TRIANGLE, Sample( 0, 2 ) );
00087 }
00088 
00089 void IdealTargetTest::test_tri_edge()
00090 {
00091     do_test( TRIANGLE, Sample( 1, 0 ) );
00092     do_test( TRIANGLE, Sample( 1, 1 ) );
00093     do_test( TRIANGLE, Sample( 1, 2 ) );
00094 }
00095 
00096 void IdealTargetTest::test_tri_center()
00097 {
00098     do_test( TRIANGLE, Sample( 2, 0 ) );
00099 }
00100 
00101 void IdealTargetTest::test_hex_corner()
00102 {
00103     do_test( HEXAHEDRON, Sample( 0, 0 ) );
00104     do_test( HEXAHEDRON, Sample( 0, 1 ) );
00105     do_test( HEXAHEDRON, Sample( 0, 6 ) );
00106     do_test( HEXAHEDRON, Sample( 0, 7 ) );
00107 }
00108 
00109 void IdealTargetTest::test_hex_edge()
00110 {
00111     do_test( HEXAHEDRON, Sample( 1, 1 ) );
00112     do_test( HEXAHEDRON, Sample( 1, 4 ) );
00113     do_test( HEXAHEDRON, Sample( 1, 11 ) );
00114 }
00115 
00116 void IdealTargetTest::test_hex_face()
00117 {
00118     do_test( HEXAHEDRON, Sample( 2, 0 ) );
00119     do_test( HEXAHEDRON, Sample( 2, 1 ) );
00120     do_test( HEXAHEDRON, Sample( 2, 2 ) );
00121     do_test( HEXAHEDRON, Sample( 2, 3 ) );
00122     do_test( HEXAHEDRON, Sample( 2, 4 ) );
00123     do_test( HEXAHEDRON, Sample( 2, 5 ) );
00124 }
00125 
00126 void IdealTargetTest::test_hex_center()
00127 {
00128     do_test( HEXAHEDRON, Sample( 3, 0 ) );
00129 }
00130 
00131 void IdealTargetTest::get_calc_target( EntityTopology type, Sample location, MsqMatrix< 3, 3 >& w3,
00132                                        MsqMatrix< 2, 2 >& w2 )
00133 {
00134     MsqPrintError err( std::cout );
00135     const int elem_dim = TopologyInfo::dimension( type );
00136 
00137     // create a patch -- actual coords and such don't really matter
00138     std::vector< double > coords( 24, 0.0 );
00139     const size_t conn[] = { 0, 1, 2, 3, 4, 5, 6, 7 };
00140     PatchData pd;
00141     pd.fill( 8, arrptr( coords ), 1, type, conn, 0, err );
00142     CPPUNIT_ASSERT( !MSQ_CHKERR( err ) );
00143     pd.attach_settings( &settings );
00144 
00145     IdealShapeTarget tc;
00146     if( elem_dim == 2 )
00147         tc.get_2D_target( pd, 0, location, w2, err );
00148     else
00149         tc.get_3D_target( pd, 0, location, w3, err );
00150     CPPUNIT_ASSERT( !MSQ_CHKERR( err ) );
00151 }
00152 
00153 void IdealTargetTest::get_ideal_target( EntityTopology type, Sample location, MsqMatrix< 3, 3 >& w3,
00154                                         MsqMatrix< 2, 2 >& w2 )
00155 {
00156     MsqPrintError err( std::cout );
00157     const unsigned elem_dim = TopologyInfo::dimension( type );
00158 
00159     // get the target matrix for an ideal element
00160     size_t indices[100];
00161     size_t num_vtx;
00162     const Vector3D* coords = unit_element( type );
00163     Vector3D c[3];
00164     if( elem_dim == 2 )
00165     {
00166         MsqVector< 2 > derivs[100];
00167         const MappingFunction2D* func = settings.get_mapping_function_2D( type );
00168         func->derivatives( location, NodeSet(), indices, derivs, num_vtx, err );
00169         CPPUNIT_ASSERT( !MSQ_CHKERR( err ) );
00170 
00171         MsqMatrix< 3, 2 > J;
00172         for( size_t i = 0; i < num_vtx; ++i )
00173             for( unsigned j = 0; j < 2; ++j )
00174                 c[j] += derivs[i][j] * coords[indices[i]];
00175 
00176         for( unsigned i = 0; i < 3; ++i )
00177             for( unsigned j = 0; j < 2; ++j )
00178                 J( i, j ) = c[j][i];
00179 
00180         w2 = TargetCalculator::skew( J );
00181     }
00182     else
00183     {
00184         MsqVector< 3 > derivs[100];
00185         const MappingFunction3D* func = settings.get_mapping_function_3D( type );
00186         func->derivatives( location, NodeSet(), indices, derivs, num_vtx, err );
00187         CPPUNIT_ASSERT( !MSQ_CHKERR( err ) );
00188 
00189         for( size_t i = 0; i < num_vtx; ++i )
00190             for( unsigned j = 0; j < 3; ++j )
00191                 c[j] += derivs[i][j] * coords[indices[i]];
00192 
00193         for( unsigned i = 0; i < 3; ++i )
00194             for( unsigned j = 0; j < 3; ++j )
00195                 w3( i, j ) = c[j][i];
00196 
00197         w3 = TargetCalculator::skew( w3 );
00198     }
00199 }
00200 
00201 void IdealTargetTest::do_test( EntityTopology type, Sample location )
00202 {
00203     MsqMatrix< 3, 3 > w3_calc, w3_exp;
00204     MsqMatrix< 2, 2 > w2_calc, w2_exp;
00205     get_calc_target( type, location, w3_calc, w2_calc );
00206     get_ideal_target( type, location, w3_exp, w2_exp );
00207     if( TopologyInfo::dimension( type ) == 2 )
00208     {
00209         CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, det( w2_calc ), 1e-6 );
00210         CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, det( w2_exp ), 1e-6 );
00211         // a rotation of the expected matrix is acceptable.
00212         MsqMatrix< 2, 2 > R = inverse( w2_calc ) * w2_exp;
00213         ASSERT_MATRICES_EQUAL( transpose( R ), inverse( R ), 1e-6 );
00214     }
00215     else
00216     {
00217         MsqMatrix< 3, 3 > R = inverse( w3_calc ) * w3_exp;
00218         ASSERT_MATRICES_EQUAL( transpose( R ), inverse( R ), 1e-6 );
00219     }
00220 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines