MOAB: Mesh Oriented datABase  (version 5.4.1)
ConditionNumberFunctions.hpp
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 // -*- Mode : c++; tab-width: 3; c-tab-always-indent: t; indent-tabs-mode: nil; c-basic-offset: 3
00028 // -*-
00029 
00030 /*! \file ConditionNumberFunctions.hpp
00031 
00032 Header file for the MBMesquite::ShapeQualityMetric class
00033 
00034   \author Thomas Leurent
00035   \date   2002-09-01
00036  */
00037 
00038 #ifndef ConditionNumberFunctions_hpp
00039 #define ConditionNumberFunctions_hpp
00040 
00041 #include "Mesquite.hpp"
00042 #include "MsqError.hpp"
00043 #include "QualityMetric.hpp"
00044 #include "PatchData.hpp"
00045 
00046 namespace MBMesquite
00047 {
00048 static inline bool condition_number_2d( const Vector3D temp_vec[],
00049                                         size_t e_ind,
00050                                         PatchData& pd,
00051                                         double& fval,
00052                                         MsqError& err )
00053 {
00054     // norm squared of J
00055     double term1 = temp_vec[0] % temp_vec[0] + temp_vec[1] % temp_vec[1];
00056 
00057     Vector3D unit_surf_norm;
00058     pd.get_domain_normal_at_element( e_ind, unit_surf_norm, err );
00059     MSQ_ERRZERO( err );
00060     unit_surf_norm.normalize();
00061 
00062     // det J
00063     double temp_var = unit_surf_norm % ( temp_vec[0] * temp_vec[1] );
00064 
00065     // revert to old, non-barrier form
00066     if( temp_var <= 0.0 ) return false;
00067     fval = term1 / ( 2.0 * temp_var );
00068     return true;
00069 
00070     /*
00071     double h;
00072     double delta=pd.get_barrier_delta(err); MSQ_ERRZERO(err);
00073 
00074     // Note: technically, we want delta=eta*tau-max
00075     //       whereas the function above gives delta=eta*alpha-max
00076     //
00077     //       Because the only requirement on eta is eta << 1,
00078     //       and because tau-max = alpha-max/0.707 we can
00079     //       ignore the discrepancy
00080 
00081     if (delta==0) {
00082        if (temp_var < MSQ_DBL_MIN ) {
00083           return false;
00084        }
00085        else {
00086           h=temp_var;
00087        }
00088 
00089     // Note: when delta=0, the vertex_barrier_function
00090     //       formally gives h=temp_var as well.
00091     //       We just do it this way to avoid any
00092     //       roundoff issues.
00093     // Also: when delta=0, this metric is identical
00094     //       to the original condition number with
00095     //       the barrier at temp_var=0
00096     }
00097     else {
00098        h = QualityMetric::vertex_barrier_function(temp_var,delta);
00099 
00100        if (h<MSQ_DBL_MIN && fabs(temp_var) > MSQ_DBL_MIN ) {
00101          h = delta*delta/fabs(temp_var); }
00102        // Note: Analytically, h is strictly positive, but
00103        //       it can be zero numerically if temp_var
00104        //       is a large negative number
00105        //       In the case h=0, we use a different analytic
00106        //       approximation to compute h.
00107     }
00108 
00109     if (h<MSQ_DBL_MIN) {
00110       MSQ_SETERR(err)( "Barrier function is zero due to excessively large "
00111                        "negative area compared to delta. /n Try to untangle "
00112                        "mesh another way. ", MsqError::INVALID_MESH);
00113       return false;
00114     }
00115 
00116     fval=term1/(2*h);
00117 
00118     if (fval>MSQ_MAX_CAP) {
00119        fval=MSQ_MAX_CAP;
00120     }
00121     return true;
00122     */
00123 }
00124 
00125 //} //namespace
00126 
00127 static inline bool condition_number_3d( const Vector3D temp_vec[], PatchData& /*pd*/, double& fval, MsqError& /*err*/ )
00128 {
00129     // norm squared of J
00130     double term1 = temp_vec[0] % temp_vec[0] + temp_vec[1] % temp_vec[1] + temp_vec[2] % temp_vec[2];
00131     // norm squared of adjoint of J
00132     double term2 = ( temp_vec[0] * temp_vec[1] ) % ( temp_vec[0] * temp_vec[1] ) +
00133                    ( temp_vec[1] * temp_vec[2] ) % ( temp_vec[1] * temp_vec[2] ) +
00134                    ( temp_vec[2] * temp_vec[0] ) % ( temp_vec[2] * temp_vec[0] );
00135     // det of J
00136     double temp_var = temp_vec[0] % ( temp_vec[1] * temp_vec[2] );
00137 
00138     // revert to old, non-barrier formulation
00139     if( temp_var <= 0.0 ) return false;
00140     fval = sqrt( term1 * term2 ) / ( 3.0 * temp_var );
00141     return true;
00142 
00143     /*
00144     double h;
00145     double delta=pd.get_barrier_delta(err); MSQ_ERRZERO(err);
00146 
00147     // Note: technically, we want delta=eta*tau-max
00148     //       whereas the function above gives delta=eta*alpha-max
00149     //
00150     //       Because the only requirement on eta is eta << 1,
00151     //       and because tau-max = alpha-max/0.707 we can
00152     //       ignore the discrepancy
00153 
00154     if (delta==0) {
00155        if (temp_var < MSQ_DBL_MIN ) {
00156           return false;
00157        }
00158        else {
00159           h=temp_var;
00160        }
00161 
00162     // Note: when delta=0, the vertex_barrier_function
00163     //       formally gives h=temp_var as well.
00164     //       We just do it this way to avoid any
00165     //       roundoff issues.
00166     // Also: when delta=0, this metric is identical
00167     //       to the original condition number with
00168     //       the barrier at temp_var=0
00169 
00170     }
00171     else {
00172        h = QualityMetric::vertex_barrier_function(temp_var,delta);
00173 
00174        if (h<MSQ_DBL_MIN && fabs(temp_var) > MSQ_DBL_MIN ) {
00175          h = delta*delta/fabs(temp_var); }
00176 
00177        // Note: Analytically, h is strictly positive, but
00178        //       it can be zero numerically if temp_var
00179        //       is a large negative number
00180        //       In the h=0, we use a different analytic
00181        //       approximation to compute h.
00182     }
00183     if (h<MSQ_DBL_MIN) {
00184       MSQ_SETERR(err)("Barrier function is zero due to excessively large "
00185                       "negative area compared to delta. /n Try to untangle "
00186                       "mesh another way. ", MsqError::INVALID_MESH);
00187       return false;
00188     }
00189 
00190     fval=sqrt(term1*term2)/(3*h);
00191 
00192     if (fval>MSQ_MAX_CAP) {
00193        fval=MSQ_MAX_CAP;
00194     }
00195     return true;
00196     */
00197 }
00198 
00199 }  // namespace MBMesquite
00200 
00201 #endif  // ConditionNumberFunctions_hpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines