Branch data Line data Source code
1 : : /* *****************************************************************
2 : : MESQUITE -- The Mesh Quality Improvement Toolkit
3 : :
4 : : Copyright 2006 Sandia National Laboratories. Developed at the
5 : : University of Wisconsin--Madison under SNL contract number
6 : : 624796. The U.S. Government and the University of Wisconsin
7 : : retain certain rights to this software.
8 : :
9 : : This library is free software; you can redistribute it and/or
10 : : modify it under the terms of the GNU Lesser General Public
11 : : License as published by the Free Software Foundation; either
12 : : version 2.1 of the License, or (at your option) any later version.
13 : :
14 : : This library is distributed in the hope that it will be useful,
15 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 : : Lesser General Public License for more details.
18 : :
19 : : You should have received a copy of the GNU Lesser General Public License
20 : : (lgpl.txt) along with this library; if not, write to the Free Software
21 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 : :
23 : : (2006) [email protected]
24 : :
25 : : ***************************************************************** */
26 : :
27 : : /** \file TRel2DShapeSizeOrientBarrierAlt1.cpp
28 : : * \brief
29 : : * \author Jason Kraftcheck
30 : : */
31 : :
32 : : #include "Mesquite.hpp"
33 : : #include "TShapeSizeOrientB2.hpp"
34 : : #include "MsqMatrix.hpp"
35 : : #include "MsqError.hpp"
36 : : #include "TMPDerivs.hpp"
37 : :
38 : : namespace MBMesquite
39 : : {
40 : :
41 : 0 : std::string TShapeSizeOrientB2::get_name() const
42 : : {
43 [ # # ]: 0 : return "TShapeSizeOrientB2";
44 : : }
45 : :
46 [ # # ]: 0 : TShapeSizeOrientB2::~TShapeSizeOrientB2() {}
47 : :
48 : 24380 : bool TShapeSizeOrientB2::evaluate( const MsqMatrix< 2, 2 >& T, double& result, MsqError& err )
49 : : {
50 [ + - ]: 24380 : double d = det( T );
51 [ + - ][ - + ]: 24380 : if( TMetric::invalid_determinant( d ) )
52 : : {
53 [ # # ][ # # ]: 0 : MSQ_SETERR( err )( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
54 : 0 : return false;
55 : : }
56 [ + - ][ + - ]: 24380 : MsqMatrix< 2, 2 > T_inv = 1 / d * adj( T );
57 [ + - ]: 24380 : pluseq_scaled_I( T_inv, -1.0 );
58 [ + - ]: 24380 : result = sqr_Frobenius( T_inv );
59 : 24380 : return true;
60 : : }
61 : :
62 : 0 : bool TShapeSizeOrientB2::evaluate( const MsqMatrix< 3, 3 >& T, double& result, MsqError& err )
63 : : {
64 [ # # ]: 0 : double d = det( T );
65 [ # # ][ # # ]: 0 : if( TMetric::invalid_determinant( d ) )
66 : : {
67 [ # # ][ # # ]: 0 : MSQ_SETERR( err )( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
68 : 0 : return false;
69 : : }
70 [ # # ][ # # ]: 0 : MsqMatrix< 3, 3 > T_inv = 1 / d * adj( T );
71 [ # # ]: 0 : pluseq_scaled_I( T_inv, -1.0 );
72 [ # # ]: 0 : result = sqr_Frobenius( T_inv );
73 : 0 : return true;
74 : : }
75 : :
76 : : /** \f$ \frac{1}{\tau^2}|T|^2 - \frac{2}{\tau}tr(adj T) + 2 \f$ */
77 : 28280 : bool TShapeSizeOrientB2::evaluate_with_grad( const MsqMatrix< 2, 2 >& T, double& result, MsqMatrix< 2, 2 >& deriv_wrt_T,
78 : : MsqError& err )
79 : : {
80 [ + - ]: 28280 : const double tau = det( T );
81 [ + - ][ + + ]: 28280 : if( invalid_determinant( tau ) )
82 : : {
83 [ + - ][ + - ]: 1 : MSQ_SETERR( err )( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
84 : 1 : return false;
85 : : }
86 : :
87 [ + - ]: 28279 : const MsqMatrix< 2, 2 > adjt = transpose_adj( T );
88 : 28279 : const double it = 1.0 / tau;
89 [ + - ][ + - ]: 28279 : result = it * ( it * sqr_Frobenius( T ) - 2.0 * trace( T ) ) + 2.0;
90 : 28279 : deriv_wrt_T = T;
91 [ + - ]: 28279 : deriv_wrt_T *= it * it;
92 [ + - ]: 28279 : deriv_wrt_T( 0, 0 ) -= it;
93 [ + - ]: 28279 : deriv_wrt_T( 1, 1 ) -= it;
94 [ + - ][ + - ]: 28279 : deriv_wrt_T += it * it * ( trace( T ) - it * sqr_Frobenius( T ) ) * adjt;
[ + - ][ + - ]
95 [ + - ]: 28279 : deriv_wrt_T *= 2.0;
96 : 28280 : return true;
97 : : }
98 : :
99 : : /** \f$ \frac{1}{\tau^2}|adj T|^2 - \frac{2}{\tau}tr(adj T) + 3 \f$ */
100 : 0 : bool TShapeSizeOrientB2::evaluate_with_grad( const MsqMatrix< 3, 3 >& T, double& result, MsqMatrix< 3, 3 >& deriv_wrt_T,
101 : : MsqError& err )
102 : : {
103 [ # # ]: 0 : const double tau = det( T );
104 [ # # ][ # # ]: 0 : if( invalid_determinant( tau ) )
105 : : {
106 [ # # ][ # # ]: 0 : MSQ_SETERR( err )( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
107 : 0 : return false;
108 : : }
109 : :
110 [ # # ]: 0 : const MsqMatrix< 3, 3 > adjt = adj( T );
111 : 0 : const double it = 1.0 / tau;
112 [ # # ][ # # ]: 0 : result = it * ( it * sqr_Frobenius( adjt ) - 2.0 * trace( adjt ) ) + 3.0;
113 : :
114 : 0 : deriv_wrt_T = T;
115 [ # # ][ # # ]: 0 : deriv_wrt_T *= sqr_Frobenius( T );
116 [ # # ][ # # ]: 0 : deriv_wrt_T -= T * transpose( T ) * T;
[ # # ][ # # ]
117 [ # # ]: 0 : deriv_wrt_T *= it * it;
118 : :
119 [ # # ][ # # ]: 0 : deriv_wrt_T += it * it * ( trace( adjt ) - it * sqr_Frobenius( adjt ) ) * transpose( adjt );
[ # # ][ # # ]
[ # # ]
120 : :
121 [ # # ]: 0 : double f = trace( T ) * it;
122 [ # # ]: 0 : deriv_wrt_T( 0, 0 ) -= f;
123 [ # # ]: 0 : deriv_wrt_T( 1, 1 ) -= f;
124 [ # # ]: 0 : deriv_wrt_T( 2, 2 ) -= f;
125 : :
126 [ # # ][ # # ]: 0 : deriv_wrt_T += it * transpose( T );
[ # # ]
127 : :
128 [ # # ]: 0 : deriv_wrt_T *= 2.0;
129 : 0 : return true;
130 : : }
131 : :
132 : 0 : bool TShapeSizeOrientB2::evaluate_with_hess( const MsqMatrix< 2, 2 >& T, double& result, MsqMatrix< 2, 2 >& deriv_wrt_T,
133 : : MsqMatrix< 2, 2 > second[3], MsqError& err )
134 : : {
135 [ # # ]: 0 : const double tau = det( T );
136 [ # # ][ # # ]: 0 : if( invalid_determinant( tau ) )
137 : : {
138 [ # # ][ # # ]: 0 : MSQ_SETERR( err )( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
139 : 0 : return false;
140 : : }
141 : :
142 [ # # ]: 0 : const MsqMatrix< 2, 2 > adjt = transpose_adj( T );
143 : 0 : const double it = 1.0 / tau;
144 [ # # ][ # # ]: 0 : result = it * ( it * sqr_Frobenius( T ) - 2.0 * trace( T ) ) + 2.0;
145 : 0 : deriv_wrt_T = T;
146 [ # # ]: 0 : deriv_wrt_T *= it * it;
147 [ # # ]: 0 : deriv_wrt_T( 0, 0 ) -= it;
148 [ # # ]: 0 : deriv_wrt_T( 1, 1 ) -= it;
149 [ # # ][ # # ]: 0 : deriv_wrt_T += it * it * ( trace( T ) - it * sqr_Frobenius( T ) ) * adjt;
[ # # ][ # # ]
150 [ # # ]: 0 : deriv_wrt_T *= 2.0;
151 : :
152 [ # # ][ # # ]: 0 : set_scaled_outer_product( second, it * it * it * ( 6 * it * sqr_Frobenius( T ) - 4 * trace( T ) ), adjt );
[ # # ]
153 [ # # ]: 0 : pluseq_scaled_I( second, 2 * it * it );
154 [ # # ][ # # ]: 0 : pluseq_scaled_2nd_deriv_of_det( second, 2 * it * it * ( trace( T ) - it * sqr_Frobenius( T ) ) );
[ # # ]
155 [ # # ]: 0 : pluseq_scaled_sum_outer_product( second, -4 * it * it * it, T, adjt );
156 [ # # ]: 0 : pluseq_scaled_sum_outer_product_I( second, 2 * it * it, adjt );
157 : :
158 : 0 : return true;
159 : : }
160 : :
161 : 0 : bool TShapeSizeOrientB2::evaluate_with_hess( const MsqMatrix< 3, 3 >& T, double& result, MsqMatrix< 3, 3 >& deriv_wrt_T,
162 : : MsqMatrix< 3, 3 > second[6], MsqError& err )
163 : : {
164 [ # # ]: 0 : const double tau = det( T );
165 [ # # ][ # # ]: 0 : if( invalid_determinant( tau ) )
166 : : {
167 [ # # ][ # # ]: 0 : MSQ_SETERR( err )( barrier_violated_msg, MsqError::BARRIER_VIOLATED );
168 : 0 : return false;
169 : : }
170 : :
171 [ # # ]: 0 : const MsqMatrix< 3, 3 > adjt = adj( T );
172 : 0 : const double it = 1.0 / tau;
173 [ # # ]: 0 : const double nadjt = sqr_Frobenius( adjt );
174 [ # # ]: 0 : const double nT = sqr_Frobenius( T );
175 [ # # ]: 0 : const double tadjT = trace( adjt );
176 : 0 : result = it * ( it * nadjt - 2.0 * tadjT ) + 3.0;
177 : :
178 [ # # ][ # # ]: 0 : const MsqMatrix< 3, 3 > TTtT = T * transpose( T ) * T;
[ # # ]
179 : 0 : deriv_wrt_T = T;
180 [ # # ]: 0 : deriv_wrt_T *= nT;
181 [ # # ]: 0 : deriv_wrt_T -= TTtT;
182 [ # # ]: 0 : deriv_wrt_T *= it * it;
183 : :
184 [ # # ][ # # ]: 0 : deriv_wrt_T += it * it * ( tadjT - it * nadjt ) * transpose( adjt );
[ # # ]
185 : :
186 [ # # ]: 0 : const double tT = trace( T );
187 : 0 : double f = tT * it;
188 [ # # ]: 0 : deriv_wrt_T( 0, 0 ) -= f;
189 [ # # ]: 0 : deriv_wrt_T( 1, 1 ) -= f;
190 [ # # ]: 0 : deriv_wrt_T( 2, 2 ) -= f;
191 : :
192 [ # # ][ # # ]: 0 : deriv_wrt_T += it * transpose( T );
[ # # ]
193 : :
194 [ # # ]: 0 : deriv_wrt_T *= 2.0;
195 : :
196 [ # # ]: 0 : set_scaled_2nd_deriv_norm_sqr_adj( second, it * it, T );
197 : :
198 : 0 : const double yf = -it * it * it * it;
199 : 0 : const double sf = -2;
200 : 0 : const double zf = -it * it * sf;
201 : :
202 [ # # ]: 0 : pluseq_scaled_2nd_deriv_of_det( second, yf * 2 * nadjt * tau + zf * tadjT, T );
203 [ # # ][ # # ]: 0 : pluseq_scaled_outer_product( second, yf * -6 * nadjt - 2 * zf * tadjT * it, transpose( adjt ) );
204 [ # # ][ # # ]: 0 : MsqMatrix< 3, 3 > dnadj_dT = 2 * ( nT * T - TTtT );
[ # # ]
205 [ # # ][ # # ]: 0 : pluseq_scaled_sum_outer_product( second, yf * 2 * tau, dnadj_dT, transpose( adjt ) );
206 [ # # ]: 0 : pluseq_scaled_2nd_deriv_tr_adj( second, sf * it );
207 [ # # ][ # # ]: 0 : MsqMatrix< 3, 3 > dtradj_dT = -transpose( T );
208 [ # # ]: 0 : dtradj_dT( 0, 0 ) += tT;
209 [ # # ]: 0 : dtradj_dT( 1, 1 ) += tT;
210 [ # # ]: 0 : dtradj_dT( 2, 2 ) += tT;
211 [ # # ][ # # ]: 0 : pluseq_scaled_sum_outer_product( second, zf, dtradj_dT, transpose( adjt ) );
212 : :
213 : 0 : return true;
214 : : }
215 : :
216 [ + - ][ + - ]: 8 : } // namespace MBMesquite
|