MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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