MOAB: Mesh Oriented datABase  (version 5.4.1)
TShapeSizeOrientB2.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     retain 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) [email protected]
00024 
00025   ***************************************************************** */
00026 
00027 /** \file TRel2DShapeSizeOrientBarrierAlt1.cpp
00028  *  \brief
00029  *  \author Jason Kraftcheck
00030  */
00031 
00032 #include "Mesquite.hpp"
00033 #include "TShapeSizeOrientB2.hpp"
00034 #include "MsqMatrix.hpp"
00035 #include "MsqError.hpp"
00036 #include "TMPDerivs.hpp"
00037 
00038 namespace MBMesquite
00039 {
00040 
00041 std::string TShapeSizeOrientB2::get_name() const
00042 {
00043     return "TShapeSizeOrientB2";
00044 }
00045 
00046 TShapeSizeOrientB2::~TShapeSizeOrientB2() {}
00047 
00048 bool TShapeSizeOrientB2::evaluate( const MsqMatrix< 2, 2 >& T, double& result, MsqError& err )
00049 {
00050     double d = det( T );
00051     if( TMetric::invalid_determinant( d ) )
00052     {
00053         MSQ_SETERR( err )( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
00054         return false;
00055     }
00056     MsqMatrix< 2, 2 > T_inv = 1 / d * adj( T );
00057     pluseq_scaled_I( T_inv, -1.0 );
00058     result = sqr_Frobenius( T_inv );
00059     return true;
00060 }
00061 
00062 bool TShapeSizeOrientB2::evaluate( const MsqMatrix< 3, 3 >& T, double& result, MsqError& err )
00063 {
00064     double d = det( T );
00065     if( TMetric::invalid_determinant( d ) )
00066     {
00067         MSQ_SETERR( err )( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
00068         return false;
00069     }
00070     MsqMatrix< 3, 3 > T_inv = 1 / d * adj( T );
00071     pluseq_scaled_I( T_inv, -1.0 );
00072     result = sqr_Frobenius( T_inv );
00073     return true;
00074 }
00075 
00076 /** \f$ \frac{1}{\tau^2}|T|^2 - \frac{2}{\tau}tr(adj T) + 2 \f$ */
00077 bool TShapeSizeOrientB2::evaluate_with_grad( const MsqMatrix< 2, 2 >& T,
00078                                              double& result,
00079                                              MsqMatrix< 2, 2 >& deriv_wrt_T,
00080                                              MsqError& err )
00081 {
00082     const double tau = det( T );
00083     if( invalid_determinant( tau ) )
00084     {
00085         MSQ_SETERR( err )( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
00086         return false;
00087     }
00088 
00089     const MsqMatrix< 2, 2 > adjt = transpose_adj( T );
00090     const double it              = 1.0 / tau;
00091     result                       = it * ( it * sqr_Frobenius( T ) - 2.0 * trace( T ) ) + 2.0;
00092     deriv_wrt_T                  = T;
00093     deriv_wrt_T *= it * it;
00094     deriv_wrt_T( 0, 0 ) -= it;
00095     deriv_wrt_T( 1, 1 ) -= it;
00096     deriv_wrt_T += it * it * ( trace( T ) - it * sqr_Frobenius( T ) ) * adjt;
00097     deriv_wrt_T *= 2.0;
00098     return true;
00099 }
00100 
00101 /** \f$ \frac{1}{\tau^2}|adj T|^2 - \frac{2}{\tau}tr(adj T) + 3 \f$ */
00102 bool TShapeSizeOrientB2::evaluate_with_grad( const MsqMatrix< 3, 3 >& T,
00103                                              double& result,
00104                                              MsqMatrix< 3, 3 >& deriv_wrt_T,
00105                                              MsqError& err )
00106 {
00107     const double tau = det( T );
00108     if( invalid_determinant( tau ) )
00109     {
00110         MSQ_SETERR( err )( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
00111         return false;
00112     }
00113 
00114     const MsqMatrix< 3, 3 > adjt = adj( T );
00115     const double it              = 1.0 / tau;
00116     result                       = it * ( it * sqr_Frobenius( adjt ) - 2.0 * trace( adjt ) ) + 3.0;
00117 
00118     deriv_wrt_T = T;
00119     deriv_wrt_T *= sqr_Frobenius( T );
00120     deriv_wrt_T -= T * transpose( T ) * T;
00121     deriv_wrt_T *= it * it;
00122 
00123     deriv_wrt_T += it * it * ( trace( adjt ) - it * sqr_Frobenius( adjt ) ) * transpose( adjt );
00124 
00125     double f = trace( T ) * it;
00126     deriv_wrt_T( 0, 0 ) -= f;
00127     deriv_wrt_T( 1, 1 ) -= f;
00128     deriv_wrt_T( 2, 2 ) -= f;
00129 
00130     deriv_wrt_T += it * transpose( T );
00131 
00132     deriv_wrt_T *= 2.0;
00133     return true;
00134 }
00135 
00136 bool TShapeSizeOrientB2::evaluate_with_hess( const MsqMatrix< 2, 2 >& T,
00137                                              double& result,
00138                                              MsqMatrix< 2, 2 >& deriv_wrt_T,
00139                                              MsqMatrix< 2, 2 > second[3],
00140                                              MsqError& err )
00141 {
00142     const double tau = det( T );
00143     if( invalid_determinant( tau ) )
00144     {
00145         MSQ_SETERR( err )( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
00146         return false;
00147     }
00148 
00149     const MsqMatrix< 2, 2 > adjt = transpose_adj( T );
00150     const double it              = 1.0 / tau;
00151     result                       = it * ( it * sqr_Frobenius( T ) - 2.0 * trace( T ) ) + 2.0;
00152     deriv_wrt_T                  = T;
00153     deriv_wrt_T *= it * it;
00154     deriv_wrt_T( 0, 0 ) -= it;
00155     deriv_wrt_T( 1, 1 ) -= it;
00156     deriv_wrt_T += it * it * ( trace( T ) - it * sqr_Frobenius( T ) ) * adjt;
00157     deriv_wrt_T *= 2.0;
00158 
00159     set_scaled_outer_product( second, it * it * it * ( 6 * it * sqr_Frobenius( T ) - 4 * trace( T ) ), adjt );
00160     pluseq_scaled_I( second, 2 * it * it );
00161     pluseq_scaled_2nd_deriv_of_det( second, 2 * it * it * ( trace( T ) - it * sqr_Frobenius( T ) ) );
00162     pluseq_scaled_sum_outer_product( second, -4 * it * it * it, T, adjt );
00163     pluseq_scaled_sum_outer_product_I( second, 2 * it * it, adjt );
00164 
00165     return true;
00166 }
00167 
00168 bool TShapeSizeOrientB2::evaluate_with_hess( const MsqMatrix< 3, 3 >& T,
00169                                              double& result,
00170                                              MsqMatrix< 3, 3 >& deriv_wrt_T,
00171                                              MsqMatrix< 3, 3 > second[6],
00172                                              MsqError& err )
00173 {
00174     const double tau = det( T );
00175     if( invalid_determinant( tau ) )
00176     {
00177         MSQ_SETERR( err )( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
00178         return false;
00179     }
00180 
00181     const MsqMatrix< 3, 3 > adjt = adj( T );
00182     const double it              = 1.0 / tau;
00183     const double nadjt           = sqr_Frobenius( adjt );
00184     const double nT              = sqr_Frobenius( T );
00185     const double tadjT           = trace( adjt );
00186     result                       = it * ( it * nadjt - 2.0 * tadjT ) + 3.0;
00187 
00188     const MsqMatrix< 3, 3 > TTtT = T * transpose( T ) * T;
00189     deriv_wrt_T                  = T;
00190     deriv_wrt_T *= nT;
00191     deriv_wrt_T -= TTtT;
00192     deriv_wrt_T *= it * it;
00193 
00194     deriv_wrt_T += it * it * ( tadjT - it * nadjt ) * transpose( adjt );
00195 
00196     const double tT = trace( T );
00197     double f        = tT * it;
00198     deriv_wrt_T( 0, 0 ) -= f;
00199     deriv_wrt_T( 1, 1 ) -= f;
00200     deriv_wrt_T( 2, 2 ) -= f;
00201 
00202     deriv_wrt_T += it * transpose( T );
00203 
00204     deriv_wrt_T *= 2.0;
00205 
00206     set_scaled_2nd_deriv_norm_sqr_adj( second, it * it, T );
00207 
00208     const double yf = -it * it * it * it;
00209     const double sf = -2;
00210     const double zf = -it * it * sf;
00211 
00212     pluseq_scaled_2nd_deriv_of_det( second, yf * 2 * nadjt * tau + zf * tadjT, T );
00213     pluseq_scaled_outer_product( second, yf * -6 * nadjt - 2 * zf * tadjT * it, transpose( adjt ) );
00214     MsqMatrix< 3, 3 > dnadj_dT = 2 * ( nT * T - TTtT );
00215     pluseq_scaled_sum_outer_product( second, yf * 2 * tau, dnadj_dT, transpose( adjt ) );
00216     pluseq_scaled_2nd_deriv_tr_adj( second, sf * it );
00217     MsqMatrix< 3, 3 > dtradj_dT = -transpose( T );
00218     dtradj_dT( 0, 0 ) += tT;
00219     dtradj_dT( 1, 1 ) += tT;
00220     dtradj_dT( 2, 2 ) += tT;
00221     pluseq_scaled_sum_outer_product( second, zf, dtradj_dT, transpose( adjt ) );
00222 
00223     return true;
00224 }
00225 
00226 }  // namespace MBMesquite
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines