MOAB: Mesh Oriented datABase  (version 5.4.1)
IdealWeightMeanRatio.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2004 Sandia Corporation and Argonne National
00005     Laboratory.  Under the terms of Contract DE-AC04-94AL85000
00006     with Sandia Corporation, the U.S. Government 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     [email protected], [email protected], [email protected],
00024     [email protected], [email protected], [email protected]
00025 
00026   ***************************************************************** */
00027 /*!
00028   \file   IdealWeightMeanRatio.cpp
00029   \brief
00030 
00031   \author Michael Brewer
00032   \date   2002-11-11
00033 */
00034 #include "IdealWeightMeanRatio.hpp"
00035 #include "MeanRatioFunctions.hpp"
00036 #include "Vector3D.hpp"
00037 #include "MsqTimer.hpp"
00038 #include "MsqDebug.hpp"
00039 #include "MsqError.hpp"
00040 #include "PatchData.hpp"
00041 
00042 #include <cmath>
00043 #include <vector>
00044 using std::vector;
00045 
00046 using namespace MBMesquite;
00047 
00048 std::string IdealWeightMeanRatio::get_name() const
00049 {
00050     return "Mean Ratio";
00051 }
00052 
00053 int IdealWeightMeanRatio::get_negate_flag() const
00054 {
00055     return -1;
00056 }
00057 
00058 bool IdealWeightMeanRatio::evaluate( PatchData& pd, size_t handle, double& m, MsqError& err )
00059 {
00060     const MsqMeshEntity* e = &pd.element_by_index( handle );
00061     EntityTopology topo    = e->get_element_type();
00062 
00063     const MsqVertex* vertices = pd.get_vertex_array( err );
00064     const size_t* v_i         = e->get_vertex_index_array();
00065 
00066     Vector3D n;  // Surface normal for 2D objects
00067 
00068     // Prism and Hex element descriptions
00069     static const int locs_pri[6][4] = { { 0, 1, 2, 3 }, { 1, 2, 0, 4 }, { 2, 0, 1, 5 },
00070                                         { 3, 5, 4, 0 }, { 4, 3, 5, 1 }, { 5, 4, 3, 2 } };
00071     static const int locs_hex[8][4] = { { 0, 1, 3, 4 }, { 1, 2, 0, 5 }, { 2, 3, 1, 6 }, { 3, 0, 2, 7 },
00072                                         { 4, 7, 5, 0 }, { 5, 4, 6, 1 }, { 6, 5, 7, 2 }, { 7, 6, 4, 3 } };
00073 
00074     const Vector3D d_con( 1.0, 1.0, 1.0 );
00075 
00076     int i;
00077 
00078     m                 = 0.0;
00079     bool metric_valid = false;
00080     switch( topo )
00081     {
00082         case TRIANGLE:
00083             pd.get_domain_normal_at_element( e, n, err );
00084             MSQ_ERRZERO( err );
00085             n            = n / n.length();  // Need unit normal
00086             mCoords[0]   = vertices[v_i[0]];
00087             mCoords[1]   = vertices[v_i[1]];
00088             mCoords[2]   = vertices[v_i[2]];
00089             metric_valid = m_fcn_2e( m, mCoords, n, a2Con, b2Con, c2Con );
00090             if( !metric_valid ) return false;
00091             break;
00092 
00093         case QUADRILATERAL:
00094             pd.get_domain_normal_at_element( e, n, err );
00095             MSQ_ERRZERO( err );
00096             for( i = 0; i < 4; ++i )
00097             {
00098                 n            = n / n.length();  // Need unit normal
00099                 mCoords[0]   = vertices[v_i[locs_hex[i][0]]];
00100                 mCoords[1]   = vertices[v_i[locs_hex[i][1]]];
00101                 mCoords[2]   = vertices[v_i[locs_hex[i][2]]];
00102                 metric_valid = m_fcn_2i( mMetrics[i], mCoords, n, a2Con, b2Con, c2Con, d_con );
00103                 if( !metric_valid ) return false;
00104             }
00105             m = average_metrics( mMetrics, 4, err );
00106             MSQ_ERRZERO( err );
00107             break;
00108 
00109         case TETRAHEDRON:
00110             mCoords[0]   = vertices[v_i[0]];
00111             mCoords[1]   = vertices[v_i[1]];
00112             mCoords[2]   = vertices[v_i[2]];
00113             mCoords[3]   = vertices[v_i[3]];
00114             metric_valid = m_fcn_3e( m, mCoords, a3Con, b3Con, c3Con );
00115             if( !metric_valid ) return false;
00116             break;
00117 
00118         case PYRAMID:
00119             for( i = 0; i < 4; ++i )
00120             {
00121                 mCoords[0]   = vertices[v_i[i]];
00122                 mCoords[1]   = vertices[v_i[( i + 1 ) % 4]];
00123                 mCoords[2]   = vertices[v_i[( i + 3 ) % 4]];
00124                 mCoords[3]   = vertices[v_i[4]];
00125                 metric_valid = m_fcn_3p( mMetrics[i], mCoords, a3Con, b3Con, c3Con );
00126                 if( !metric_valid ) return false;
00127             }
00128             m = average_metrics( mMetrics, 4, err );
00129             MSQ_ERRZERO( err );
00130             break;
00131 
00132         case PRISM:
00133             for( i = 0; i < 6; ++i )
00134             {
00135                 mCoords[0]   = vertices[v_i[locs_pri[i][0]]];
00136                 mCoords[1]   = vertices[v_i[locs_pri[i][1]]];
00137                 mCoords[2]   = vertices[v_i[locs_pri[i][2]]];
00138                 mCoords[3]   = vertices[v_i[locs_pri[i][3]]];
00139                 metric_valid = m_fcn_3w( mMetrics[i], mCoords, a3Con, b3Con, c3Con );
00140                 if( !metric_valid ) return false;
00141             }
00142             m = average_metrics( mMetrics, 6, err );
00143             MSQ_ERRZERO( err );
00144             break;
00145 
00146         case HEXAHEDRON:
00147             for( i = 0; i < 8; ++i )
00148             {
00149                 mCoords[0]   = vertices[v_i[locs_hex[i][0]]];
00150                 mCoords[1]   = vertices[v_i[locs_hex[i][1]]];
00151                 mCoords[2]   = vertices[v_i[locs_hex[i][2]]];
00152                 mCoords[3]   = vertices[v_i[locs_hex[i][3]]];
00153                 metric_valid = m_fcn_3i( mMetrics[i], mCoords, a3Con, b3Con, c3Con, d_con );
00154                 if( !metric_valid ) return false;
00155             }
00156             m = average_metrics( mMetrics, 8, err );
00157             MSQ_ERRZERO( err );
00158             break;
00159 
00160         default:
00161             MSQ_SETERR( err )
00162             ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not supported in IdealWeightMeanRatio", (int)topo );
00163             return false;
00164     }  // end switch over element type
00165     return true;
00166 }
00167 
00168 bool IdealWeightMeanRatio::evaluate_with_gradient( PatchData& pd,
00169                                                    size_t handle,
00170                                                    double& m,
00171                                                    std::vector< size_t >& indices,
00172                                                    std::vector< Vector3D >& g,
00173                                                    MsqError& err )
00174 {
00175     //  FUNCTION_TIMER_START(__FUNC__);
00176     const MsqMeshEntity* e = &pd.element_by_index( handle );
00177     EntityTopology topo    = e->get_element_type();
00178 
00179     if( !analytical_average_gradient() && topo != TRIANGLE && topo != TETRAHEDRON )
00180     {
00181         static bool print = true;
00182         if( print )
00183         {
00184             MSQ_DBGOUT( 1 ) << "Analyical gradient not available for selected averaging scheme. "
00185                             << "Using (possibly much slower) numerical approximation of gradient"
00186                             << " of quality metric. " << std::endl;
00187             print = false;
00188         }
00189         return QualityMetric::evaluate_with_gradient( pd, handle, m, indices, g, err );
00190     }
00191 
00192     const MsqVertex* vertices = pd.get_vertex_array( err );
00193     const size_t* v_i         = e->get_vertex_index_array();
00194 
00195     Vector3D n;  // Surface normal for 2D objects
00196 
00197     // double   nm, t=0;
00198 
00199     // Prism and Hex element descriptions
00200     static const int locs_pri[6][4] = { { 0, 1, 2, 3 }, { 1, 2, 0, 4 }, { 2, 0, 1, 5 },
00201                                         { 3, 5, 4, 0 }, { 4, 3, 5, 1 }, { 5, 4, 3, 2 } };
00202     static const int locs_hex[8][4] = { { 0, 1, 3, 4 }, { 1, 2, 0, 5 }, { 2, 3, 1, 6 }, { 3, 0, 2, 7 },
00203                                         { 4, 7, 5, 0 }, { 5, 4, 6, 1 }, { 6, 5, 7, 2 }, { 7, 6, 4, 3 } };
00204 
00205     const Vector3D d_con( 1.0, 1.0, 1.0 );
00206 
00207     int i;
00208 
00209     bool metric_valid = false;
00210     const uint32_t fm = fixed_vertex_bitmap( pd, e, indices );
00211 
00212     m = 0.0;
00213 
00214     switch( topo )
00215     {
00216         case TRIANGLE:
00217             pd.get_domain_normal_at_element( e, n, err );
00218             MSQ_ERRZERO( err );
00219             n          = n / n.length();  // Need unit normal
00220             mCoords[0] = vertices[v_i[0]];
00221             mCoords[1] = vertices[v_i[1]];
00222             mCoords[2] = vertices[v_i[2]];
00223             g.resize( 3 );
00224             if( !g_fcn_2e( m, arrptr( g ), mCoords, n, a2Con, b2Con, c2Con ) ) return false;
00225             break;
00226 
00227         case QUADRILATERAL:
00228             pd.get_domain_normal_at_element( e, n, err );
00229             MSQ_ERRZERO( err );
00230             n /= n.length();  // Need unit normal
00231             for( i = 0; i < 4; ++i )
00232             {
00233                 mCoords[0] = vertices[v_i[locs_hex[i][0]]];
00234                 mCoords[1] = vertices[v_i[locs_hex[i][1]]];
00235                 mCoords[2] = vertices[v_i[locs_hex[i][2]]];
00236                 if( !g_fcn_2i( mMetrics[i], mGradients + 3 * i, mCoords, n, a2Con, b2Con, c2Con, d_con ) ) return false;
00237             }
00238 
00239             g.resize( 4 );
00240             m = average_corner_gradients( QUADRILATERAL, fm, 4, mMetrics, mGradients, arrptr( g ), err );
00241             MSQ_ERRZERO( err );
00242             break;
00243 
00244         case TETRAHEDRON:
00245             mCoords[0] = vertices[v_i[0]];
00246             mCoords[1] = vertices[v_i[1]];
00247             mCoords[2] = vertices[v_i[2]];
00248             mCoords[3] = vertices[v_i[3]];
00249             g.resize( 4 );
00250             metric_valid = g_fcn_3e( m, arrptr( g ), mCoords, a3Con, b3Con, c3Con );
00251             if( !metric_valid ) return false;
00252             break;
00253 
00254         case PYRAMID:
00255             for( i = 0; i < 4; ++i )
00256             {
00257                 mCoords[0]   = vertices[v_i[i]];
00258                 mCoords[1]   = vertices[v_i[( i + 1 ) % 4]];
00259                 mCoords[2]   = vertices[v_i[( i + 3 ) % 4]];
00260                 mCoords[3]   = vertices[v_i[4]];
00261                 metric_valid = g_fcn_3p( mMetrics[i], mGradients + 4 * i, mCoords, a3Con, b3Con, c3Con );
00262                 if( !metric_valid ) return false;
00263             }
00264             g.resize( 5 );
00265             m = average_corner_gradients( PYRAMID, fm, 4, mMetrics, mGradients, arrptr( g ), err );
00266             MSQ_ERRZERO( err );
00267             break;
00268 
00269         case PRISM:
00270             for( i = 0; i < 6; ++i )
00271             {
00272                 mCoords[0] = vertices[v_i[locs_pri[i][0]]];
00273                 mCoords[1] = vertices[v_i[locs_pri[i][1]]];
00274                 mCoords[2] = vertices[v_i[locs_pri[i][2]]];
00275                 mCoords[3] = vertices[v_i[locs_pri[i][3]]];
00276                 if( !g_fcn_3w( mMetrics[i], mGradients + 4 * i, mCoords, a3Con, b3Con, c3Con ) ) return false;
00277             }
00278             g.resize( 6 );
00279             m = average_corner_gradients( PRISM, fm, 6, mMetrics, mGradients, arrptr( g ), err );
00280             MSQ_ERRZERO( err );
00281             break;
00282 
00283         case HEXAHEDRON:
00284             for( i = 0; i < 8; ++i )
00285             {
00286                 mCoords[0] = vertices[v_i[locs_hex[i][0]]];
00287                 mCoords[1] = vertices[v_i[locs_hex[i][1]]];
00288                 mCoords[2] = vertices[v_i[locs_hex[i][2]]];
00289                 mCoords[3] = vertices[v_i[locs_hex[i][3]]];
00290                 if( !g_fcn_3i( mMetrics[i], mGradients + 4 * i, mCoords, a3Con, b3Con, c3Con, d_con ) ) return false;
00291             }
00292             g.resize( 8 );
00293             m = average_corner_gradients( HEXAHEDRON, fm, 8, mMetrics, mGradients, arrptr( g ), err );
00294             MSQ_ERRZERO( err );
00295             break;
00296 
00297         default:
00298             MSQ_SETERR( err )
00299             ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not supported in IdealWeightMeanRatio", (int)topo );
00300             return false;
00301     }
00302 
00303     remove_fixed_gradients( topo, fm, g );
00304     return true;
00305 }
00306 
00307 bool IdealWeightMeanRatio::evaluate_with_Hessian_diagonal( PatchData& pd,
00308                                                            size_t handle,
00309                                                            double& m,
00310                                                            std::vector< size_t >& indices,
00311                                                            std::vector< Vector3D >& g,
00312                                                            std::vector< SymMatrix3D >& h,
00313                                                            MsqError& err )
00314 {
00315     const MsqMeshEntity* e = &pd.element_by_index( handle );
00316     EntityTopology topo    = e->get_element_type();
00317 
00318     if( !analytical_average_hessian() && topo != TRIANGLE && topo != TETRAHEDRON )
00319     {
00320         static bool print = true;
00321         if( print )
00322         {
00323             MSQ_DBGOUT( 1 ) << "Analyical gradient not available for selected averaging scheme. "
00324                             << "Using (possibly much slower) numerical approximation of gradient"
00325                             << " of quality metric. " << std::endl;
00326             print = false;
00327         }
00328         return QualityMetric::evaluate_with_Hessian_diagonal( pd, handle, m, indices, g, h, err );
00329     }
00330 
00331     const MsqVertex* vertices = pd.get_vertex_array( err );
00332     const size_t* v_i         = e->get_vertex_index_array();
00333 
00334     Vector3D n;  // Surface normal for 2D objects
00335 
00336     // Prism and Hex element descriptions
00337     static const int locs_pri[6][4] = { { 0, 1, 2, 3 }, { 1, 2, 0, 4 }, { 2, 0, 1, 5 },
00338                                         { 3, 5, 4, 0 }, { 4, 3, 5, 1 }, { 5, 4, 3, 2 } };
00339     static const int locs_hex[8][4] = { { 0, 1, 3, 4 }, { 1, 2, 0, 5 }, { 2, 3, 1, 6 }, { 3, 0, 2, 7 },
00340                                         { 4, 7, 5, 0 }, { 5, 4, 6, 1 }, { 6, 5, 7, 2 }, { 7, 6, 4, 3 } };
00341 
00342     const Vector3D d_con( 1.0, 1.0, 1.0 );
00343 
00344     int i;
00345 
00346     bool metric_valid = false;
00347     const uint32_t fm = fixed_vertex_bitmap( pd, e, indices );
00348 
00349     m = 0.0;
00350 
00351     switch( topo )
00352     {
00353         case TRIANGLE:
00354             pd.get_domain_normal_at_element( e, n, err );
00355             MSQ_ERRZERO( err );
00356             n          = n / n.length();  // Need unit normal
00357             mCoords[0] = vertices[v_i[0]];
00358             mCoords[1] = vertices[v_i[1]];
00359             mCoords[2] = vertices[v_i[2]];
00360             g.resize( 3 ), h.resize( 3 );
00361             if( !h_fcn_2e( m, arrptr( g ), mHessians, mCoords, n, a2Con, b2Con, c2Con ) ) return false;
00362             h[0] = mHessians[0].upper();
00363             h[1] = mHessians[3].upper();
00364             h[2] = mHessians[5].upper();
00365             break;
00366 
00367         case QUADRILATERAL:
00368             pd.get_domain_normal_at_element( e, n, err );
00369             MSQ_ERRZERO( err );
00370             n = n / n.length();  // Need unit normal
00371             for( i = 0; i < 4; ++i )
00372             {
00373                 mCoords[0] = vertices[v_i[locs_hex[i][0]]];
00374                 mCoords[1] = vertices[v_i[locs_hex[i][1]]];
00375                 mCoords[2] = vertices[v_i[locs_hex[i][2]]];
00376                 if( !h_fcn_2i( mMetrics[i], mGradients + 3 * i, mHessians + 6 * i, mCoords, n, a2Con, b2Con, c2Con,
00377                                d_con ) )
00378                     return false;
00379             }
00380 
00381             g.resize( 4 ), h.resize( 4 );
00382             m = average_corner_hessian_diagonals( QUADRILATERAL, fm, 4, mMetrics, mGradients, mHessians, arrptr( g ),
00383                                                   arrptr( h ), err );
00384             MSQ_ERRZERO( err );
00385             break;
00386 
00387         case TETRAHEDRON:
00388             mCoords[0] = vertices[v_i[0]];
00389             mCoords[1] = vertices[v_i[1]];
00390             mCoords[2] = vertices[v_i[2]];
00391             mCoords[3] = vertices[v_i[3]];
00392             g.resize( 4 ), h.resize( 4 );
00393             metric_valid = h_fcn_3e( m, arrptr( g ), mHessians, mCoords, a3Con, b3Con, c3Con );
00394             if( !metric_valid ) return false;
00395             h[0] = mHessians[0].upper();
00396             h[1] = mHessians[4].upper();
00397             h[2] = mHessians[7].upper();
00398             h[3] = mHessians[9].upper();
00399             break;
00400 
00401         case PYRAMID:
00402             for( i = 0; i < 4; ++i )
00403             {
00404                 mCoords[0] = vertices[v_i[i]];
00405                 mCoords[1] = vertices[v_i[( i + 1 ) % 4]];
00406                 mCoords[2] = vertices[v_i[( i + 3 ) % 4]];
00407                 mCoords[3] = vertices[v_i[4]];
00408                 metric_valid =
00409                     h_fcn_3p( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con );
00410                 if( !metric_valid ) return false;
00411             }
00412 
00413             g.resize( 5 ), h.resize( 5 );
00414             m = average_corner_hessian_diagonals( PYRAMID, fm, 4, mMetrics, mGradients, mHessians, arrptr( g ),
00415                                                   arrptr( h ), err );
00416             MSQ_ERRZERO( err );
00417             break;
00418 
00419         case PRISM:
00420             for( i = 0; i < 6; ++i )
00421             {
00422                 mCoords[0] = vertices[v_i[locs_pri[i][0]]];
00423                 mCoords[1] = vertices[v_i[locs_pri[i][1]]];
00424                 mCoords[2] = vertices[v_i[locs_pri[i][2]]];
00425                 mCoords[3] = vertices[v_i[locs_pri[i][3]]];
00426                 if( !h_fcn_3w( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con ) )
00427                     return false;
00428             }
00429 
00430             g.resize( 6 ), h.resize( 6 );
00431             m = average_corner_hessian_diagonals( PRISM, fm, 6, mMetrics, mGradients, mHessians, arrptr( g ),
00432                                                   arrptr( h ), err );
00433             MSQ_ERRZERO( err );
00434             break;
00435 
00436         case HEXAHEDRON:
00437             for( i = 0; i < 8; ++i )
00438             {
00439                 mCoords[0] = vertices[v_i[locs_hex[i][0]]];
00440                 mCoords[1] = vertices[v_i[locs_hex[i][1]]];
00441                 mCoords[2] = vertices[v_i[locs_hex[i][2]]];
00442                 mCoords[3] = vertices[v_i[locs_hex[i][3]]];
00443                 if( !h_fcn_3i( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con,
00444                                d_con ) )
00445                     return false;
00446             }
00447 
00448             g.resize( 8 ), h.resize( 8 );
00449             m = average_corner_hessian_diagonals( HEXAHEDRON, fm, 8, mMetrics, mGradients, mHessians, arrptr( g ),
00450                                                   arrptr( h ), err );
00451             MSQ_ERRZERO( err );
00452             break;
00453 
00454         default:
00455             MSQ_SETERR( err )
00456             ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not supported in IdealWeightMeanRatio", (int)topo );
00457             return false;
00458     }  // end switch over element type
00459 
00460     remove_fixed_diagonals( topo, fm, g, h );
00461     return true;
00462 }
00463 
00464 bool IdealWeightMeanRatio::evaluate_with_Hessian( PatchData& pd,
00465                                                   size_t handle,
00466                                                   double& m,
00467                                                   std::vector< size_t >& indices,
00468                                                   std::vector< Vector3D >& g,
00469                                                   std::vector< Matrix3D >& h,
00470                                                   MsqError& err )
00471 {
00472     //  FUNCTION_TIMER_START(__FUNC__);
00473     const MsqMeshEntity* e = &pd.element_by_index( handle );
00474     EntityTopology topo    = e->get_element_type();
00475 
00476     if( !analytical_average_hessian() && topo != TRIANGLE && topo != TETRAHEDRON )
00477     {
00478         static bool print = true;
00479         if( print )
00480         {
00481             MSQ_DBGOUT( 1 ) << "Analyical gradient not available for selected averaging scheme. "
00482                             << "Using (possibly much slower) numerical approximation of gradient"
00483                             << " of quality metric. " << std::endl;
00484             print = false;
00485         }
00486         return QualityMetric::evaluate_with_Hessian( pd, handle, m, indices, g, h, err );
00487     }
00488 
00489     const MsqVertex* vertices = pd.get_vertex_array( err );
00490     const size_t* v_i         = e->get_vertex_index_array();
00491 
00492     Vector3D n;  // Surface normal for 2D objects
00493 
00494     // Prism and Hex element descriptions
00495     static const int locs_pri[6][4] = { { 0, 1, 2, 3 }, { 1, 2, 0, 4 }, { 2, 0, 1, 5 },
00496                                         { 3, 5, 4, 0 }, { 4, 3, 5, 1 }, { 5, 4, 3, 2 } };
00497     static const int locs_hex[8][4] = { { 0, 1, 3, 4 }, { 1, 2, 0, 5 }, { 2, 3, 1, 6 }, { 3, 0, 2, 7 },
00498                                         { 4, 7, 5, 0 }, { 5, 4, 6, 1 }, { 6, 5, 7, 2 }, { 7, 6, 4, 3 } };
00499 
00500     const Vector3D d_con( 1.0, 1.0, 1.0 );
00501 
00502     int i;
00503 
00504     bool metric_valid = false;
00505     const uint32_t fm = fixed_vertex_bitmap( pd, e, indices );
00506 
00507     m = 0.0;
00508 
00509     switch( topo )
00510     {
00511         case TRIANGLE:
00512             pd.get_domain_normal_at_element( e, n, err );
00513             MSQ_ERRZERO( err );
00514             n          = n / n.length();  // Need unit normal
00515             mCoords[0] = vertices[v_i[0]];
00516             mCoords[1] = vertices[v_i[1]];
00517             mCoords[2] = vertices[v_i[2]];
00518             g.resize( 3 ), h.resize( 6 );
00519             if( !h_fcn_2e( m, arrptr( g ), arrptr( h ), mCoords, n, a2Con, b2Con, c2Con ) ) return false;
00520             break;
00521 
00522         case QUADRILATERAL:
00523             pd.get_domain_normal_at_element( e, n, err );
00524             MSQ_ERRZERO( err );
00525             n = n / n.length();  // Need unit normal
00526             for( i = 0; i < 4; ++i )
00527             {
00528                 mCoords[0] = vertices[v_i[locs_hex[i][0]]];
00529                 mCoords[1] = vertices[v_i[locs_hex[i][1]]];
00530                 mCoords[2] = vertices[v_i[locs_hex[i][2]]];
00531                 if( !h_fcn_2i( mMetrics[i], mGradients + 3 * i, mHessians + 6 * i, mCoords, n, a2Con, b2Con, c2Con,
00532                                d_con ) )
00533                     return false;
00534             }
00535 
00536             g.resize( 4 ), h.resize( 10 );
00537             m = average_corner_hessians( QUADRILATERAL, fm, 4, mMetrics, mGradients, mHessians, arrptr( g ),
00538                                          arrptr( h ), err );
00539             MSQ_ERRZERO( err );
00540             break;
00541 
00542         case TETRAHEDRON:
00543             mCoords[0] = vertices[v_i[0]];
00544             mCoords[1] = vertices[v_i[1]];
00545             mCoords[2] = vertices[v_i[2]];
00546             mCoords[3] = vertices[v_i[3]];
00547             g.resize( 4 ), h.resize( 10 );
00548             metric_valid = h_fcn_3e( m, arrptr( g ), arrptr( h ), mCoords, a3Con, b3Con, c3Con );
00549             if( !metric_valid ) return false;
00550             break;
00551 
00552         case PYRAMID:
00553             for( i = 0; i < 4; ++i )
00554             {
00555                 mCoords[0] = vertices[v_i[i]];
00556                 mCoords[1] = vertices[v_i[( i + 1 ) % 4]];
00557                 mCoords[2] = vertices[v_i[( i + 3 ) % 4]];
00558                 mCoords[3] = vertices[v_i[4]];
00559                 metric_valid =
00560                     h_fcn_3p( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con );
00561                 if( !metric_valid ) return false;
00562             }
00563 
00564             g.resize( 5 ), h.resize( 15 );
00565             m = average_corner_hessians( PYRAMID, fm, 4, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ),
00566                                          err );
00567             MSQ_ERRZERO( err );
00568             break;
00569 
00570         case PRISM:
00571             for( i = 0; i < 6; ++i )
00572             {
00573                 mCoords[0] = vertices[v_i[locs_pri[i][0]]];
00574                 mCoords[1] = vertices[v_i[locs_pri[i][1]]];
00575                 mCoords[2] = vertices[v_i[locs_pri[i][2]]];
00576                 mCoords[3] = vertices[v_i[locs_pri[i][3]]];
00577                 if( !h_fcn_3w( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con ) )
00578                     return false;
00579             }
00580 
00581             g.resize( 6 ), h.resize( 21 );
00582             m = average_corner_hessians( PRISM, fm, 6, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ), err );
00583             MSQ_ERRZERO( err );
00584             break;
00585 
00586         case HEXAHEDRON:
00587             for( i = 0; i < 8; ++i )
00588             {
00589                 mCoords[0] = vertices[v_i[locs_hex[i][0]]];
00590                 mCoords[1] = vertices[v_i[locs_hex[i][1]]];
00591                 mCoords[2] = vertices[v_i[locs_hex[i][2]]];
00592                 mCoords[3] = vertices[v_i[locs_hex[i][3]]];
00593                 if( !h_fcn_3i( mMetrics[i], mGradients + 4 * i, mHessians + 10 * i, mCoords, a3Con, b3Con, c3Con,
00594                                d_con ) )
00595                     return false;
00596             }
00597 
00598             g.resize( 8 ), h.resize( 36 );
00599             m = average_corner_hessians( HEXAHEDRON, fm, 8, mMetrics, mGradients, mHessians, arrptr( g ), arrptr( h ),
00600                                          err );
00601             MSQ_ERRZERO( err );
00602             break;
00603 
00604         default:
00605             MSQ_SETERR( err )
00606             ( MsqError::UNSUPPORTED_ELEMENT, "Element type (%d) not supported in IdealWeightMeanRatio", (int)topo );
00607             return false;
00608     }  // end switch over element type
00609 
00610     remove_fixed_gradients( topo, fm, g );
00611     remove_fixed_hessians( topo, fm, h );
00612     //  FUNCTION_TIMER_END();
00613     return true;
00614 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines