MOAB: Mesh Oriented datABase
(version 5.4.1)
|
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 diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov, 00024 pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov 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 MeanRatioFunctions.hpp 00031 00032 Header that defines generalized Mean Ratio function, gradient, and hessian 00033 evaluations. 00034 00035 \author Todd Munson 00036 \date 2003-06-11 00037 */ 00038 00039 #ifndef MeanRatioFunctions_hpp 00040 #define MeanRatioFunctions_hpp 00041 00042 #include <cmath> 00043 #include "Mesquite.hpp" 00044 #include "Vector3D.hpp" 00045 #include "Matrix3D.hpp" 00046 #include "Exponent.hpp" 00047 00048 namespace MBMesquite 00049 { 00050 /***************************************************************************/ 00051 /* Gradient calculation courtesy of Paul Hovland. The code was modified */ 00052 /* to reduce the number of flops and intermediate variables, and improve */ 00053 /* the locality of reference. */ 00054 /***************************************************************************/ 00055 /* The Hessian calculation is computes everyting in (x,y,z) blocks and */ 00056 /* stores only the upper triangular blocks. The results are put into */ 00057 /* (c1,c2,c3,c4) order prior to returning the Hessian matrix. */ 00058 /***************************************************************************/ 00059 /* The form of the function, gradient, and Hessian follows: */ 00060 /* o(x) = a * pow(f(A(x)), b) * pow(g(A(x)), c) */ 00061 /* where A(x) is the incidence matrix generated by: */ 00062 /* [x1-x0 x2-x0 x3-x0] */ 00063 /* A(x) = [y1-y0 y2-y0 y3-y0] * inv(W) */ 00064 /* [z1-z0 z2-z0 z3-z0] */ 00065 /* and f() is the squared Frobenius norm of A(x), and g() is the */ 00066 /* determinant of A(x). */ 00067 /* */ 00068 /* The gradient is calculated as follows: */ 00069 /* alpha := a*b*pow(f(A(x)),b-1)*pow(g(A(x)),c) */ 00070 /* beta := a*c*pow(f(A(x)),b)*pow(g(A(x)),c-1) */ 00071 /* */ 00072 /* do/dx = (alpha * (df/dA) + beta * (dg/dA)) (dA/dx) */ 00073 /* */ 00074 /* (df/dA)_i = 2*A_i */ 00075 /* (dg/dA)_i = A_j*A_k - A_l*A_m for some {j,k,l,m} */ 00076 /* */ 00077 /* d^2o/dx^2 = (dA/dx)' * ((d alpha/dA) * (df/dA) + */ 00078 /* (d beta/dA) * (dg/dA) */ 00079 /* alpha * (d^2f/dA^2) */ 00080 /* beta * (d^2g/dA^2)) * (dA/dx) */ 00081 /* */ 00082 /* Note: since A(x) is a linear function, there are no terms involving */ 00083 /* d^2A/dx^2 since this matrix is zero. */ 00084 /* */ 00085 /* gamma := a*b*c*pow(f(A(x)),b-1)*pow(g(A(x)),c-1) */ 00086 /* delta := a*c*(c-1)*pow(f(A(x)),b)*pow(g(A(x)),c-2) */ 00087 /* psi := a*b*(b-1)*pow(f(A(x)),b-2)*pow(g(A(x)),c) */ 00088 /* */ 00089 /* d^2o/dx^2 = (dA/dx)' * (gamma*((dg/dA)'*(df/dA) + (df/dA)'*(dg/dA)) + */ 00090 /* delta* (dg/dA)'*(dg/dA) + */ 00091 /* psi* (df/dA)'*(df/dA) + */ 00092 /* alpha*(d^2f/dA^2) + */ 00093 /* beta*(d^2g/dA^2)) * (dA/dx) */ 00094 /* */ 00095 /* Note: (df/dA) and (dg/dA) are row vectors and we only calculate the */ 00096 /* upper triangular part of the inner matrices. */ 00097 /* */ 00098 /* For regular tetrahedral elements, we have the following: */ 00099 /* */ 00100 /* [-1 1 0 0 ] */ 00101 /* M = [-sqrt(3) -sqrt(3) 2*sqrt(3) 0 ] */ 00102 /* [-sqrt(6) -sqrt(6) -sqrt(6) 3*sqrt(6) ] */ 00103 /* */ 00104 /* [M 0 0] */ 00105 /* dA/dx = [0 M 0] */ 00106 /* [0 0 M] */ 00107 /***************************************************************************/ 00108 00109 /*****************************************************************************/ 00110 /* Not all compilers substitute out constants (especially the square root). */ 00111 /* Therefore, they are substituted out manually. The values below were */ 00112 /* calculated on a solaris machine using long doubles. I believe they are */ 00113 /* accurate. */ 00114 /*****************************************************************************/ 00115 00116 #define isqrt3 5.77350269189625797959429519858e-01 /* 1.0/sqrt(3.0)*/ 00117 #define tisqrt3 1.15470053837925159591885903972e+00 /* 2.0/sqrt(3.0)*/ 00118 #define isqrt6 4.08248290463863052509822647505e-01 /* 1.0/sqrt(6.0)*/ 00119 #define tisqrt6 1.22474487139158915752946794252e+00 /* 3.0/sqrt(6.0)*/ 00120 00121 /*****************************************************************************/ 00122 /* The following set of functions reference triangular elements to an */ 00123 /* equilateral triangle in the plane defined by the normal. They are */ 00124 /* used when assessing the quality of a triangular element. A zero */ 00125 /* return value indicates success, while a nonzero value indicates failure. */ 00126 /*****************************************************************************/ 00127 00128 /*****************************************************************************/ 00129 /* Function evaluation requires 44 flops. */ 00130 /* Reductions possible when b == 1 or c == 1 */ 00131 /*****************************************************************************/ 00132 inline bool m_fcn_2e( double& obj, 00133 const Vector3D x[3], 00134 const Vector3D& n, 00135 const double a, 00136 const Exponent& b, 00137 const Exponent& c ) 00138 { 00139 double matr[9], f; 00140 double g; 00141 00142 /* Calculate M = [A*inv(W) n] */ 00143 matr[0] = x[1][0] - x[0][0]; 00144 matr[1] = ( 2.0 * x[2][0] - x[1][0] - x[0][0] ) * isqrt3; 00145 matr[2] = n[0]; 00146 00147 matr[3] = x[1][1] - x[0][1]; 00148 matr[4] = ( 2.0 * x[2][1] - x[1][1] - x[0][1] ) * isqrt3; 00149 matr[5] = n[1]; 00150 00151 matr[6] = x[1][2] - x[0][2]; 00152 matr[7] = ( 2.0 * x[2][2] - x[1][2] - x[0][2] ) * isqrt3; 00153 matr[8] = n[2]; 00154 00155 /* Calculate det(M). */ 00156 g = matr[0] * ( matr[4] * matr[8] - matr[5] * matr[7] ) + matr[3] * ( matr[2] * matr[7] - matr[1] * matr[8] ) + 00157 matr[6] * ( matr[1] * matr[5] - matr[2] * matr[4] ); 00158 if( g < MSQ_MIN ) 00159 { 00160 obj = g; 00161 return false; 00162 } 00163 00164 /* Calculate norm(M). */ 00165 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[3] * matr[3] + matr[4] * matr[4] + matr[6] * matr[6] + 00166 matr[7] * matr[7]; 00167 00168 /* Calculate objective function. */ 00169 obj = a * b.raise( f ) * c.raise( g ); 00170 return true; 00171 } 00172 00173 /*****************************************************************************/ 00174 /* Gradient evaluation requires 88 flops. */ 00175 /* Reductions possible when b == 1 or c == 1 */ 00176 /*****************************************************************************/ 00177 inline bool g_fcn_2e( double& obj, 00178 Vector3D g_obj[3], 00179 const Vector3D x[3], 00180 const Vector3D& n, 00181 const double a, 00182 const Exponent& b, 00183 const Exponent& c ) 00184 { 00185 double matr[9], f; 00186 double adj_m[9], g; // adj_m[2,5,8] not used 00187 double loc1, loc2, loc3; 00188 00189 /* Calculate M = [A*inv(W) n] */ 00190 matr[0] = x[1][0] - x[0][0]; 00191 matr[1] = ( 2.0 * x[2][0] - x[1][0] - x[0][0] ) * isqrt3; 00192 matr[2] = n[0]; 00193 00194 matr[3] = x[1][1] - x[0][1]; 00195 matr[4] = ( 2.0 * x[2][1] - x[1][1] - x[0][1] ) * isqrt3; 00196 matr[5] = n[1]; 00197 00198 matr[6] = x[1][2] - x[0][2]; 00199 matr[7] = ( 2.0 * x[2][2] - x[1][2] - x[0][2] ) * isqrt3; 00200 matr[8] = n[2]; 00201 00202 /* Calculate det([n M]). */ 00203 loc1 = matr[4] * matr[8] - matr[5] * matr[7]; 00204 loc2 = matr[2] * matr[7] - matr[1] * matr[8]; 00205 loc3 = matr[1] * matr[5] - matr[2] * matr[4]; 00206 g = matr[0] * loc1 + matr[3] * loc2 + matr[6] * loc3; 00207 if( g < MSQ_MIN ) 00208 { 00209 obj = g; 00210 return false; 00211 } 00212 00213 /* Calculate norm(M). */ 00214 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[3] * matr[3] + matr[4] * matr[4] + matr[6] * matr[6] + 00215 matr[7] * matr[7]; 00216 00217 /* Calculate objective function. */ 00218 obj = a * b.raise( f ) * c.raise( g ); 00219 00220 /* Calculate the derivative of the objective function. */ 00221 f = b.value() * obj / f; /* Constant on nabla f */ 00222 g = c.value() * obj / g; /* Constant on nable g */ 00223 f *= 2.0; /* Modification for nabla f */ 00224 00225 adj_m[0] = matr[0] * f + loc1 * g; 00226 adj_m[3] = matr[3] * f + loc2 * g; 00227 adj_m[6] = matr[6] * f + loc3 * g; 00228 00229 loc1 = matr[0] * g; 00230 loc2 = matr[3] * g; 00231 loc3 = matr[6] * g; 00232 00233 adj_m[1] = matr[1] * f + loc3 * matr[5] - loc2 * matr[8]; 00234 adj_m[4] = matr[4] * f + loc1 * matr[8] - loc3 * matr[2]; 00235 adj_m[7] = matr[7] * f + loc2 * matr[2] - loc1 * matr[5]; 00236 00237 loc1 = isqrt3 * adj_m[1]; 00238 g_obj[0][0] = -adj_m[0] - loc1; 00239 g_obj[1][0] = adj_m[0] - loc1; 00240 g_obj[2][0] = 2.0 * loc1; 00241 00242 loc1 = isqrt3 * adj_m[4]; 00243 g_obj[0][1] = -adj_m[3] - loc1; 00244 g_obj[1][1] = adj_m[3] - loc1; 00245 g_obj[2][1] = 2.0 * loc1; 00246 00247 loc1 = isqrt3 * adj_m[7]; 00248 g_obj[0][2] = -adj_m[6] - loc1; 00249 g_obj[1][2] = adj_m[6] - loc1; 00250 g_obj[2][2] = 2.0 * loc1; 00251 return true; 00252 } 00253 00254 /*****************************************************************************/ 00255 /* Hessian evaluation requires 316 flops. */ 00256 /* Reductions possible when b == 1 or c == 1 */ 00257 /*****************************************************************************/ 00258 inline bool h_fcn_2e( double& obj, 00259 Vector3D g_obj[3], 00260 Matrix3D h_obj[6], 00261 const Vector3D x[3], 00262 const Vector3D& n, 00263 const double a, 00264 const Exponent& b, 00265 const Exponent& c ) 00266 { 00267 double matr[9], f; 00268 double adj_m[9], g; // adj_m[2,5,8] not used 00269 double dg[9]; // dg[2,5,8] not used 00270 double loc0, loc1, loc2, loc3, loc4; 00271 double A[12], J_A[6], J_B[9], J_C[9], cross; // only 2x2 corners used 00272 00273 /* Calculate M = [A*inv(W) n] */ 00274 matr[0] = x[1][0] - x[0][0]; 00275 matr[1] = ( 2.0 * x[2][0] - x[1][0] - x[0][0] ) * isqrt3; 00276 matr[2] = n[0]; 00277 00278 matr[3] = x[1][1] - x[0][1]; 00279 matr[4] = ( 2.0 * x[2][1] - x[1][1] - x[0][1] ) * isqrt3; 00280 matr[5] = n[1]; 00281 00282 matr[6] = x[1][2] - x[0][2]; 00283 matr[7] = ( 2.0 * x[2][2] - x[1][2] - x[0][2] ) * isqrt3; 00284 matr[8] = n[2]; 00285 00286 /* Calculate det([n M]). */ 00287 dg[0] = matr[4] * matr[8] - matr[5] * matr[7]; 00288 dg[3] = matr[2] * matr[7] - matr[1] * matr[8]; 00289 dg[6] = matr[1] * matr[5] - matr[2] * matr[4]; 00290 g = matr[0] * dg[0] + matr[3] * dg[3] + matr[6] * dg[6]; 00291 if( g < MSQ_MIN ) 00292 { 00293 obj = g; 00294 return false; 00295 } 00296 00297 /* Calculate norm(M). */ 00298 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[3] * matr[3] + matr[4] * matr[4] + matr[6] * matr[6] + 00299 matr[7] * matr[7]; 00300 00301 loc3 = f; 00302 loc4 = g; 00303 00304 /* Calculate objective function. */ 00305 obj = a * b.raise( f ) * c.raise( g ); 00306 00307 /* Calculate the derivative of the objective function. */ 00308 f = b.value() * obj / f; /* Constant on nabla f */ 00309 g = c.value() * obj / g; /* Constant on nable g */ 00310 f *= 2.0; /* Modification for nabla f */ 00311 00312 dg[1] = matr[5] * matr[6] - matr[3] * matr[8]; 00313 dg[4] = matr[0] * matr[8] - matr[2] * matr[6]; 00314 dg[7] = matr[2] * matr[3] - matr[0] * matr[5]; 00315 00316 adj_m[0] = matr[0] * f + dg[0] * g; 00317 adj_m[1] = matr[1] * f + dg[1] * g; 00318 adj_m[3] = matr[3] * f + dg[3] * g; 00319 adj_m[4] = matr[4] * f + dg[4] * g; 00320 adj_m[6] = matr[6] * f + dg[6] * g; 00321 adj_m[7] = matr[7] * f + dg[7] * g; 00322 00323 loc1 = isqrt3 * adj_m[1]; 00324 g_obj[0][0] = -adj_m[0] - loc1; 00325 g_obj[1][0] = adj_m[0] - loc1; 00326 g_obj[2][0] = 2.0 * loc1; 00327 00328 loc1 = isqrt3 * adj_m[4]; 00329 g_obj[0][1] = -adj_m[3] - loc1; 00330 g_obj[1][1] = adj_m[3] - loc1; 00331 g_obj[2][1] = 2.0 * loc1; 00332 00333 loc1 = isqrt3 * adj_m[7]; 00334 g_obj[0][2] = -adj_m[6] - loc1; 00335 g_obj[1][2] = adj_m[6] - loc1; 00336 g_obj[2][2] = 2.0 * loc1; 00337 00338 /* Calculate the hessian of the objective. */ 00339 loc0 = f; /* Constant on nabla^2 f */ 00340 loc1 = g; /* Constant on nabla^2 g */ 00341 cross = f * c.value() / loc4; /* Constant on nabla g nabla f */ 00342 f = f * ( b.value() - 1 ) / loc3; /* Constant on nabla f nabla f */ 00343 g = g * ( c.value() - 1 ) / loc4; /* Constant on nabla g nabla g */ 00344 f *= 2.0; /* Modification for nabla f */ 00345 00346 /* First block of rows */ 00347 loc3 = matr[0] * f + dg[0] * cross; 00348 loc4 = dg[0] * g + matr[0] * cross; 00349 00350 J_A[0] = loc0 + loc3 * matr[0] + loc4 * dg[0]; 00351 J_A[1] = loc3 * matr[1] + loc4 * dg[1]; 00352 J_B[0] = loc3 * matr[3] + loc4 * dg[3]; 00353 J_B[1] = loc3 * matr[4] + loc4 * dg[4]; 00354 J_C[0] = loc3 * matr[6] + loc4 * dg[6]; 00355 J_C[1] = loc3 * matr[7] + loc4 * dg[7]; 00356 00357 loc3 = matr[1] * f + dg[1] * cross; 00358 loc4 = dg[1] * g + matr[1] * cross; 00359 00360 J_A[3] = loc0 + loc3 * matr[1] + loc4 * dg[1]; 00361 J_B[3] = loc3 * matr[3] + loc4 * dg[3]; 00362 J_B[4] = loc3 * matr[4] + loc4 * dg[4]; 00363 J_C[3] = loc3 * matr[6] + loc4 * dg[6]; 00364 J_C[4] = loc3 * matr[7] + loc4 * dg[7]; 00365 00366 /* First diagonal block */ 00367 loc2 = isqrt3 * J_A[1]; 00368 A[0] = -J_A[0] - loc2; 00369 A[1] = J_A[0] - loc2; 00370 00371 loc2 = isqrt3 * J_A[3]; 00372 A[4] = -J_A[1] - loc2; 00373 A[5] = J_A[1] - loc2; 00374 A[6] = 2.0 * loc2; 00375 00376 loc2 = isqrt3 * A[4]; 00377 h_obj[0][0][0] = -A[0] - loc2; 00378 h_obj[1][0][0] = A[0] - loc2; 00379 h_obj[2][0][0] = 2.0 * loc2; 00380 00381 loc2 = isqrt3 * A[5]; 00382 h_obj[3][0][0] = A[1] - loc2; 00383 h_obj[4][0][0] = 2.0 * loc2; 00384 00385 h_obj[5][0][0] = tisqrt3 * A[6]; 00386 00387 /* First off-diagonal block */ 00388 loc2 = matr[8] * loc1; 00389 J_B[1] += loc2; 00390 J_B[3] -= loc2; 00391 00392 loc2 = isqrt3 * J_B[3]; 00393 A[0] = -J_B[0] - loc2; 00394 A[1] = J_B[0] - loc2; 00395 A[2] = 2.0 * loc2; 00396 00397 loc2 = isqrt3 * J_B[4]; 00398 A[4] = -J_B[1] - loc2; 00399 A[5] = J_B[1] - loc2; 00400 A[6] = 2.0 * loc2; 00401 00402 loc2 = isqrt3 * A[4]; 00403 h_obj[0][0][1] = -A[0] - loc2; 00404 h_obj[1][0][1] = A[0] - loc2; 00405 h_obj[2][0][1] = 2.0 * loc2; 00406 00407 loc2 = isqrt3 * A[5]; 00408 h_obj[1][1][0] = -A[1] - loc2; 00409 h_obj[3][0][1] = A[1] - loc2; 00410 h_obj[4][0][1] = 2.0 * loc2; 00411 00412 loc2 = isqrt3 * A[6]; 00413 h_obj[2][1][0] = -A[2] - loc2; 00414 h_obj[4][1][0] = A[2] - loc2; 00415 h_obj[5][0][1] = 2.0 * loc2; 00416 00417 /* Second off-diagonal block */ 00418 loc2 = matr[5] * loc1; 00419 J_C[1] -= loc2; 00420 J_C[3] += loc2; 00421 00422 loc2 = isqrt3 * J_C[3]; 00423 A[0] = -J_C[0] - loc2; 00424 A[1] = J_C[0] - loc2; 00425 A[2] = 2.0 * loc2; 00426 00427 loc2 = isqrt3 * J_C[4]; 00428 A[4] = -J_C[1] - loc2; 00429 A[5] = J_C[1] - loc2; 00430 A[6] = 2.0 * loc2; 00431 00432 loc2 = isqrt3 * A[4]; 00433 h_obj[0][0][2] = -A[0] - loc2; 00434 h_obj[1][0][2] = A[0] - loc2; 00435 h_obj[2][0][2] = 2.0 * loc2; 00436 00437 loc2 = isqrt3 * A[5]; 00438 h_obj[1][2][0] = -A[1] - loc2; 00439 h_obj[3][0][2] = A[1] - loc2; 00440 h_obj[4][0][2] = 2.0 * loc2; 00441 00442 loc2 = isqrt3 * A[6]; 00443 h_obj[2][2][0] = -A[2] - loc2; 00444 h_obj[4][2][0] = A[2] - loc2; 00445 h_obj[5][0][2] = 2.0 * loc2; 00446 00447 /* Second block of rows */ 00448 loc3 = matr[3] * f + dg[3] * cross; 00449 loc4 = dg[3] * g + matr[3] * cross; 00450 00451 J_A[0] = loc0 + loc3 * matr[3] + loc4 * dg[3]; 00452 J_A[1] = loc3 * matr[4] + loc4 * dg[4]; 00453 J_B[0] = loc3 * matr[6] + loc4 * dg[6]; 00454 J_B[1] = loc3 * matr[7] + loc4 * dg[7]; 00455 00456 loc3 = matr[4] * f + dg[4] * cross; 00457 loc4 = dg[4] * g + matr[4] * cross; 00458 00459 J_A[3] = loc0 + loc3 * matr[4] + loc4 * dg[4]; 00460 J_B[3] = loc3 * matr[6] + loc4 * dg[6]; 00461 J_B[4] = loc3 * matr[7] + loc4 * dg[7]; 00462 00463 /* Second diagonal block */ 00464 loc2 = isqrt3 * J_A[1]; 00465 A[0] = -J_A[0] - loc2; 00466 A[1] = J_A[0] - loc2; 00467 00468 loc2 = isqrt3 * J_A[3]; 00469 A[4] = -J_A[1] - loc2; 00470 A[5] = J_A[1] - loc2; 00471 A[6] = 2.0 * loc2; 00472 00473 loc2 = isqrt3 * A[4]; 00474 h_obj[0][1][1] = -A[0] - loc2; 00475 h_obj[1][1][1] = A[0] - loc2; 00476 h_obj[2][1][1] = 2.0 * loc2; 00477 00478 loc2 = isqrt3 * A[5]; 00479 h_obj[3][1][1] = A[1] - loc2; 00480 h_obj[4][1][1] = 2.0 * loc2; 00481 00482 h_obj[5][1][1] = tisqrt3 * A[6]; 00483 00484 /* Third off-diagonal block */ 00485 loc2 = matr[2] * loc1; 00486 J_B[1] += loc2; 00487 J_B[3] -= loc2; 00488 00489 loc2 = isqrt3 * J_B[3]; 00490 A[0] = -J_B[0] - loc2; 00491 A[1] = J_B[0] - loc2; 00492 A[2] = 2.0 * loc2; 00493 00494 loc2 = isqrt3 * J_B[4]; 00495 A[4] = -J_B[1] - loc2; 00496 A[5] = J_B[1] - loc2; 00497 A[6] = 2.0 * loc2; 00498 00499 loc2 = isqrt3 * A[4]; 00500 h_obj[0][1][2] = -A[0] - loc2; 00501 h_obj[1][1][2] = A[0] - loc2; 00502 h_obj[2][1][2] = 2.0 * loc2; 00503 00504 loc2 = isqrt3 * A[5]; 00505 h_obj[1][2][1] = -A[1] - loc2; 00506 h_obj[3][1][2] = A[1] - loc2; 00507 h_obj[4][1][2] = 2.0 * loc2; 00508 00509 loc2 = isqrt3 * A[6]; 00510 h_obj[2][2][1] = -A[2] - loc2; 00511 h_obj[4][2][1] = A[2] - loc2; 00512 h_obj[5][1][2] = 2.0 * loc2; 00513 00514 /* Third block of rows */ 00515 loc3 = matr[6] * f + dg[6] * cross; 00516 loc4 = dg[6] * g + matr[6] * cross; 00517 00518 J_A[0] = loc0 + loc3 * matr[6] + loc4 * dg[6]; 00519 J_A[1] = loc3 * matr[7] + loc4 * dg[7]; 00520 00521 loc3 = matr[7] * f + dg[7] * cross; 00522 loc4 = dg[7] * g + matr[7] * cross; 00523 00524 J_A[3] = loc0 + loc3 * matr[7] + loc4 * dg[7]; 00525 00526 /* Third diagonal block */ 00527 loc2 = isqrt3 * J_A[1]; 00528 A[0] = -J_A[0] - loc2; 00529 A[1] = J_A[0] - loc2; 00530 00531 loc2 = isqrt3 * J_A[3]; 00532 A[4] = -J_A[1] - loc2; 00533 A[5] = J_A[1] - loc2; 00534 A[6] = 2.0 * loc2; 00535 00536 loc2 = isqrt3 * A[4]; 00537 h_obj[0][2][2] = -A[0] - loc2; 00538 h_obj[1][2][2] = A[0] - loc2; 00539 h_obj[2][2][2] = 2.0 * loc2; 00540 00541 loc2 = isqrt3 * A[5]; 00542 h_obj[3][2][2] = A[1] - loc2; 00543 h_obj[4][2][2] = 2.0 * loc2; 00544 00545 h_obj[5][2][2] = tisqrt3 * A[6]; 00546 00547 // completes diagonal blocks. 00548 h_obj[0].fill_lower_triangle(); 00549 h_obj[3].fill_lower_triangle(); 00550 h_obj[5].fill_lower_triangle(); 00551 return true; 00552 } 00553 00554 /*****************************************************************************/ 00555 /* The following set of functions reference triangular elements to an */ 00556 /* right triangle in the plane defined by the normal. They are used when */ 00557 /* assessing the quality of a quadrilateral elements. A zero return value */ 00558 /* indicates success, while a nonzero value indicates failure. */ 00559 /*****************************************************************************/ 00560 00561 /*****************************************************************************/ 00562 /* Function evaluation -- requires 41 flops. */ 00563 /* Reductions possible when b == 1, c == 1, or d == 1 */ 00564 /*****************************************************************************/ 00565 inline bool m_fcn_2i( double& obj, 00566 const Vector3D x[3], 00567 const Vector3D& n, 00568 const double a, 00569 const Exponent& b, 00570 const Exponent& c, 00571 const Vector3D& d ) 00572 { 00573 double matr[9]; 00574 double f; 00575 double g; 00576 00577 /* Calculate M = A*inv(W). */ 00578 matr[0] = d[0] * ( x[1][0] - x[0][0] ); 00579 matr[1] = d[1] * ( x[2][0] - x[0][0] ); 00580 matr[2] = n[0]; 00581 00582 matr[3] = d[0] * ( x[1][1] - x[0][1] ); 00583 matr[4] = d[1] * ( x[2][1] - x[0][1] ); 00584 matr[5] = n[1]; 00585 00586 matr[6] = d[0] * ( x[1][2] - x[0][2] ); 00587 matr[7] = d[1] * ( x[2][2] - x[0][2] ); 00588 matr[8] = n[2]; 00589 00590 /* Calculate det(M). */ 00591 g = matr[0] * ( matr[4] * matr[8] - matr[5] * matr[7] ) + matr[3] * ( matr[2] * matr[7] - matr[1] * matr[8] ) + 00592 matr[6] * ( matr[1] * matr[5] - matr[2] * matr[4] ); 00593 if( g < MSQ_MIN ) 00594 { 00595 obj = g; 00596 return false; 00597 } 00598 00599 /* Calculate norm(M). */ 00600 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[3] * matr[3] + matr[4] * matr[4] + matr[6] * matr[6] + 00601 matr[7] * matr[7]; 00602 00603 /* Calculate objective function. */ 00604 obj = a * b.raise( f ) * c.raise( g ); 00605 return true; 00606 } 00607 00608 /*****************************************************************************/ 00609 /* Gradient requires 82 flops. */ 00610 /* Reductions possible when b == 1, c == 1, or d == 1 */ 00611 /*****************************************************************************/ 00612 inline bool g_fcn_2i( double& obj, 00613 Vector3D g_obj[3], 00614 const Vector3D x[3], 00615 const Vector3D& n, 00616 const double a, 00617 const Exponent& b, 00618 const Exponent& c, 00619 const Vector3D& d ) 00620 { 00621 double matr[9], f; 00622 double adj_m[9], g; // adj_m[2,5,8] not used 00623 double loc1, loc2, loc3; 00624 00625 /* Calculate M = [A*inv(W) n] */ 00626 matr[0] = d[0] * ( x[1][0] - x[0][0] ); 00627 matr[1] = d[1] * ( x[2][0] - x[0][0] ); 00628 matr[2] = n[0]; 00629 00630 matr[3] = d[0] * ( x[1][1] - x[0][1] ); 00631 matr[4] = d[1] * ( x[2][1] - x[0][1] ); 00632 matr[5] = n[1]; 00633 00634 matr[6] = d[0] * ( x[1][2] - x[0][2] ); 00635 matr[7] = d[1] * ( x[2][2] - x[0][2] ); 00636 matr[8] = n[2]; 00637 00638 /* Calculate det([n M]). */ 00639 loc1 = matr[4] * matr[8] - matr[5] * matr[7]; 00640 loc2 = matr[2] * matr[7] - matr[1] * matr[8]; 00641 loc3 = matr[1] * matr[5] - matr[2] * matr[4]; 00642 g = matr[0] * loc1 + matr[3] * loc2 + matr[6] * loc3; 00643 if( g < MSQ_MIN ) 00644 { 00645 obj = g; 00646 return false; 00647 } 00648 00649 /* Calculate norm(M). */ 00650 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[3] * matr[3] + matr[4] * matr[4] + matr[6] * matr[6] + 00651 matr[7] * matr[7]; 00652 00653 /* Calculate objective function. */ 00654 obj = a * b.raise( f ) * c.raise( g ); 00655 00656 /* Calculate the derivative of the objective function. */ 00657 f = b.value() * obj / f; /* Constant on nabla f */ 00658 g = c.value() * obj / g; /* Constant on nable g */ 00659 f *= 2.0; /* Modification for nabla f */ 00660 00661 adj_m[0] = d[0] * ( matr[0] * f + loc1 * g ); 00662 adj_m[3] = d[0] * ( matr[3] * f + loc2 * g ); 00663 adj_m[6] = d[0] * ( matr[6] * f + loc3 * g ); 00664 00665 loc1 = matr[0] * g; 00666 loc2 = matr[3] * g; 00667 loc3 = matr[6] * g; 00668 00669 adj_m[1] = d[1] * ( matr[1] * f + loc3 * matr[5] - loc2 * matr[8] ); 00670 adj_m[4] = d[1] * ( matr[4] * f + loc1 * matr[8] - loc3 * matr[2] ); 00671 adj_m[7] = d[1] * ( matr[7] * f + loc2 * matr[2] - loc1 * matr[5] ); 00672 00673 g_obj[0][0] = -adj_m[0] - adj_m[1]; 00674 g_obj[1][0] = adj_m[0]; 00675 g_obj[2][0] = adj_m[1]; 00676 00677 g_obj[0][1] = -adj_m[3] - adj_m[4]; 00678 g_obj[1][1] = adj_m[3]; 00679 g_obj[2][1] = adj_m[4]; 00680 00681 g_obj[0][2] = -adj_m[6] - adj_m[7]; 00682 g_obj[1][2] = adj_m[6]; 00683 g_obj[2][2] = adj_m[7]; 00684 return true; 00685 } 00686 00687 /*****************************************************************************/ 00688 /* Hessian requires 253 flops. */ 00689 /* Reductions possible when b == 1, c == 1, or d == 1 */ 00690 /*****************************************************************************/ 00691 inline bool h_fcn_2i( double& obj, 00692 Vector3D g_obj[3], 00693 Matrix3D h_obj[6], 00694 const Vector3D x[3], 00695 const Vector3D& n, 00696 const double a, 00697 const Exponent& b, 00698 const Exponent& c, 00699 const Vector3D& d ) 00700 { 00701 double matr[9], f; 00702 double adj_m[9], g; // adj_m[2,5,8] not used 00703 double dg[9]; // dg[2,5,8] not used 00704 double loc0, loc1, loc2, loc3, loc4; 00705 double A[12], J_A[6], J_B[9], J_C[9], cross; // only 2x2 corners used 00706 00707 const double scale[3] = { d[0] * d[0], d[0] * d[1], d[1] * d[1] }; 00708 00709 /* Calculate M = [A*inv(W) n] */ 00710 matr[0] = d[0] * ( x[1][0] - x[0][0] ); 00711 matr[1] = d[1] * ( x[2][0] - x[0][0] ); 00712 matr[2] = n[0]; 00713 00714 matr[3] = d[0] * ( x[1][1] - x[0][1] ); 00715 matr[4] = d[1] * ( x[2][1] - x[0][1] ); 00716 matr[5] = n[1]; 00717 00718 matr[6] = d[0] * ( x[1][2] - x[0][2] ); 00719 matr[7] = d[1] * ( x[2][2] - x[0][2] ); 00720 matr[8] = n[2]; 00721 00722 /* Calculate det([n M]). */ 00723 dg[0] = matr[4] * matr[8] - matr[5] * matr[7]; 00724 dg[3] = matr[2] * matr[7] - matr[1] * matr[8]; 00725 dg[6] = matr[1] * matr[5] - matr[2] * matr[4]; 00726 g = matr[0] * dg[0] + matr[3] * dg[3] + matr[6] * dg[6]; 00727 if( g < MSQ_MIN ) 00728 { 00729 obj = g; 00730 return false; 00731 } 00732 00733 /* Calculate norm(M). */ 00734 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[3] * matr[3] + matr[4] * matr[4] + matr[6] * matr[6] + 00735 matr[7] * matr[7]; 00736 00737 loc3 = f; 00738 loc4 = g; 00739 00740 /* Calculate objective function. */ 00741 obj = a * b.raise( f ) * c.raise( g ); 00742 00743 /* Calculate the derivative of the objective function. */ 00744 f = b.value() * obj / f; /* Constant on nabla f */ 00745 g = c.value() * obj / g; /* Constant on nable g */ 00746 f *= 2.0; /* Modification for nabla f */ 00747 00748 dg[1] = matr[5] * matr[6] - matr[3] * matr[8]; 00749 dg[4] = matr[0] * matr[8] - matr[2] * matr[6]; 00750 dg[7] = matr[2] * matr[3] - matr[0] * matr[5]; 00751 00752 adj_m[0] = d[0] * ( matr[0] * f + dg[0] * g ); 00753 adj_m[1] = d[1] * ( matr[1] * f + dg[1] * g ); 00754 adj_m[3] = d[0] * ( matr[3] * f + dg[3] * g ); 00755 adj_m[4] = d[1] * ( matr[4] * f + dg[4] * g ); 00756 adj_m[6] = d[0] * ( matr[6] * f + dg[6] * g ); 00757 adj_m[7] = d[1] * ( matr[7] * f + dg[7] * g ); 00758 00759 g_obj[0][0] = -adj_m[0] - adj_m[1]; 00760 g_obj[1][0] = adj_m[0]; 00761 g_obj[2][0] = adj_m[1]; 00762 00763 g_obj[0][1] = -adj_m[3] - adj_m[4]; 00764 g_obj[1][1] = adj_m[3]; 00765 g_obj[2][1] = adj_m[4]; 00766 00767 g_obj[0][2] = -adj_m[6] - adj_m[7]; 00768 g_obj[1][2] = adj_m[6]; 00769 g_obj[2][2] = adj_m[7]; 00770 00771 /* Calculate the hessian of the objective. */ 00772 loc0 = f; /* Constant on nabla^2 f */ 00773 loc1 = g; /* Constant on nabla^2 g */ 00774 cross = f * c.value() / loc4; /* Constant on nabla g nabla f */ 00775 f = f * ( b.value() - 1 ) / loc3; /* Constant on nabla f nabla f */ 00776 g = g * ( c.value() - 1 ) / loc4; /* Constant on nabla g nabla g */ 00777 f *= 2.0; /* Modification for nabla f */ 00778 00779 /* First block of rows */ 00780 loc3 = matr[0] * f + dg[0] * cross; 00781 loc4 = dg[0] * g + matr[0] * cross; 00782 00783 J_A[0] = loc0 + loc3 * matr[0] + loc4 * dg[0]; 00784 J_A[1] = loc3 * matr[1] + loc4 * dg[1]; 00785 J_B[0] = loc3 * matr[3] + loc4 * dg[3]; 00786 J_B[1] = loc3 * matr[4] + loc4 * dg[4]; 00787 J_C[0] = loc3 * matr[6] + loc4 * dg[6]; 00788 J_C[1] = loc3 * matr[7] + loc4 * dg[7]; 00789 00790 loc3 = matr[1] * f + dg[1] * cross; 00791 loc4 = dg[1] * g + matr[1] * cross; 00792 00793 J_A[3] = loc0 + loc3 * matr[1] + loc4 * dg[1]; 00794 J_B[3] = loc3 * matr[3] + loc4 * dg[3]; 00795 J_B[4] = loc3 * matr[4] + loc4 * dg[4]; 00796 J_C[3] = loc3 * matr[6] + loc4 * dg[6]; 00797 J_C[4] = loc3 * matr[7] + loc4 * dg[7]; 00798 00799 /* First diagonal block */ 00800 J_A[0] *= scale[0]; 00801 J_A[1] *= scale[1]; 00802 J_A[3] *= scale[2]; 00803 00804 A[0] = -J_A[0] - J_A[1]; 00805 A[4] = -J_A[1] - J_A[3]; 00806 00807 h_obj[0][0][0] = -A[0] - A[4]; 00808 h_obj[1][0][0] = A[0]; 00809 h_obj[2][0][0] = A[4]; 00810 00811 h_obj[3][0][0] = J_A[0]; 00812 h_obj[4][0][0] = J_A[1]; 00813 00814 h_obj[5][0][0] = J_A[3]; 00815 00816 /* First off-diagonal block */ 00817 loc2 = matr[8] * loc1; 00818 J_B[1] += loc2; 00819 J_B[3] -= loc2; 00820 00821 J_B[0] *= scale[0]; 00822 J_B[1] *= scale[1]; 00823 J_B[3] *= scale[1]; 00824 J_B[4] *= scale[2]; 00825 00826 A[0] = -J_B[0] - J_B[3]; 00827 A[4] = -J_B[1] - J_B[4]; 00828 00829 h_obj[0][0][1] = -A[0] - A[4]; 00830 h_obj[1][0][1] = A[0]; 00831 h_obj[2][0][1] = A[4]; 00832 00833 h_obj[1][1][0] = -J_B[0] - J_B[1]; 00834 h_obj[3][0][1] = J_B[0]; 00835 h_obj[4][0][1] = J_B[1]; 00836 00837 h_obj[2][1][0] = -J_B[3] - J_B[4]; 00838 h_obj[4][1][0] = J_B[3]; 00839 h_obj[5][0][1] = J_B[4]; 00840 00841 /* Second off-diagonal block */ 00842 loc2 = matr[5] * loc1; 00843 J_C[1] -= loc2; 00844 J_C[3] += loc2; 00845 00846 J_C[0] *= scale[0]; 00847 J_C[1] *= scale[1]; 00848 J_C[3] *= scale[1]; 00849 J_C[4] *= scale[2]; 00850 00851 A[0] = -J_C[0] - J_C[3]; 00852 A[4] = -J_C[1] - J_C[4]; 00853 00854 h_obj[0][0][2] = -A[0] - A[4]; 00855 h_obj[1][0][2] = A[0]; 00856 h_obj[2][0][2] = A[4]; 00857 00858 h_obj[1][2][0] = -J_C[0] - J_C[1]; 00859 h_obj[3][0][2] = J_C[0]; 00860 h_obj[4][0][2] = J_C[1]; 00861 00862 h_obj[2][2][0] = -J_C[3] - J_C[4]; 00863 h_obj[4][2][0] = J_C[3]; 00864 h_obj[5][0][2] = J_C[4]; 00865 00866 /* Second block of rows */ 00867 loc3 = matr[3] * f + dg[3] * cross; 00868 loc4 = dg[3] * g + matr[3] * cross; 00869 00870 J_A[0] = loc0 + loc3 * matr[3] + loc4 * dg[3]; 00871 J_A[1] = loc3 * matr[4] + loc4 * dg[4]; 00872 J_B[0] = loc3 * matr[6] + loc4 * dg[6]; 00873 J_B[1] = loc3 * matr[7] + loc4 * dg[7]; 00874 00875 loc3 = matr[4] * f + dg[4] * cross; 00876 loc4 = dg[4] * g + matr[4] * cross; 00877 00878 J_A[3] = loc0 + loc3 * matr[4] + loc4 * dg[4]; 00879 J_B[3] = loc3 * matr[6] + loc4 * dg[6]; 00880 J_B[4] = loc3 * matr[7] + loc4 * dg[7]; 00881 00882 /* Second diagonal block */ 00883 J_A[0] *= scale[0]; 00884 J_A[1] *= scale[1]; 00885 J_A[3] *= scale[2]; 00886 00887 A[0] = -J_A[0] - J_A[1]; 00888 A[4] = -J_A[1] - J_A[3]; 00889 00890 h_obj[0][1][1] = -A[0] - A[4]; 00891 h_obj[1][1][1] = A[0]; 00892 h_obj[2][1][1] = A[4]; 00893 00894 h_obj[3][1][1] = J_A[0]; 00895 h_obj[4][1][1] = J_A[1]; 00896 00897 h_obj[5][1][1] = J_A[3]; 00898 00899 /* Third off-diagonal block */ 00900 loc2 = matr[2] * loc1; 00901 J_B[1] += loc2; 00902 J_B[3] -= loc2; 00903 00904 J_B[0] *= scale[0]; 00905 J_B[1] *= scale[1]; 00906 J_B[3] *= scale[1]; 00907 J_B[4] *= scale[2]; 00908 00909 A[0] = -J_B[0] - J_B[3]; 00910 A[4] = -J_B[1] - J_B[4]; 00911 00912 h_obj[0][1][2] = -A[0] - A[4]; 00913 h_obj[1][1][2] = A[0]; 00914 h_obj[2][1][2] = A[4]; 00915 00916 h_obj[1][2][1] = -J_B[0] - J_B[1]; 00917 h_obj[3][1][2] = J_B[0]; 00918 h_obj[4][1][2] = J_B[1]; 00919 00920 h_obj[2][2][1] = -J_B[3] - J_B[4]; 00921 h_obj[4][2][1] = J_B[3]; 00922 h_obj[5][1][2] = J_B[4]; 00923 00924 /* Third block of rows */ 00925 loc3 = matr[6] * f + dg[6] * cross; 00926 loc4 = dg[6] * g + matr[6] * cross; 00927 00928 J_A[0] = loc0 + loc3 * matr[6] + loc4 * dg[6]; 00929 J_A[1] = loc3 * matr[7] + loc4 * dg[7]; 00930 00931 loc3 = matr[7] * f + dg[7] * cross; 00932 loc4 = dg[7] * g + matr[7] * cross; 00933 00934 J_A[3] = loc0 + loc3 * matr[7] + loc4 * dg[7]; 00935 00936 /* Third diagonal block */ 00937 J_A[0] *= scale[0]; 00938 J_A[1] *= scale[1]; 00939 J_A[3] *= scale[2]; 00940 00941 A[0] = -J_A[0] - J_A[1]; 00942 A[4] = -J_A[1] - J_A[3]; 00943 00944 h_obj[0][2][2] = -A[0] - A[4]; 00945 h_obj[1][2][2] = A[0]; 00946 h_obj[2][2][2] = A[4]; 00947 00948 h_obj[3][2][2] = J_A[0]; 00949 h_obj[4][2][2] = J_A[1]; 00950 00951 h_obj[5][2][2] = J_A[3]; 00952 00953 // completes diagonal blocks. 00954 h_obj[0].fill_lower_triangle(); 00955 h_obj[3].fill_lower_triangle(); 00956 h_obj[5].fill_lower_triangle(); 00957 return true; 00958 } 00959 00960 /*****************************************************************************/ 00961 /* The following set of functions reference tetrahedral elements to a */ 00962 /* regular tetrahedron. They are used when assessing the quality of a */ 00963 /* tetrahedral element. A zero return value indicates success, while */ 00964 /* a nonzero value indicates failure. */ 00965 /*****************************************************************************/ 00966 00967 /*****************************************************************************/ 00968 /* Function evaluation requires 62 flops. */ 00969 /* Reductions possible when b == 1 or c == 1 */ 00970 /*****************************************************************************/ 00971 inline bool m_fcn_3e( double& obj, const Vector3D x[4], const double a, const Exponent& b, const Exponent& c ) 00972 { 00973 double matr[9], f; 00974 double g; 00975 00976 /* Calculate M = A*inv(W). */ 00977 f = x[1][0] + x[0][0]; 00978 matr[0] = x[1][0] - x[0][0]; 00979 matr[1] = ( 2.0 * x[2][0] - f ) * isqrt3; 00980 matr[2] = ( 3.0 * x[3][0] - x[2][0] - f ) * isqrt6; 00981 00982 f = x[1][1] + x[0][1]; 00983 matr[3] = x[1][1] - x[0][1]; 00984 matr[4] = ( 2.0 * x[2][1] - f ) * isqrt3; 00985 matr[5] = ( 3.0 * x[3][1] - x[2][1] - f ) * isqrt6; 00986 00987 f = x[1][2] + x[0][2]; 00988 matr[6] = x[1][2] - x[0][2]; 00989 matr[7] = ( 2.0 * x[2][2] - f ) * isqrt3; 00990 matr[8] = ( 3.0 * x[3][2] - x[2][2] - f ) * isqrt6; 00991 00992 /* Calculate det(M). */ 00993 g = matr[0] * ( matr[4] * matr[8] - matr[5] * matr[7] ) + matr[1] * ( matr[5] * matr[6] - matr[3] * matr[8] ) + 00994 matr[2] * ( matr[3] * matr[7] - matr[4] * matr[6] ); 00995 if( g < MSQ_MIN ) 00996 { 00997 obj = g; 00998 return false; 00999 } 01000 01001 /* Calculate norm(M). */ 01002 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 01003 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 01004 01005 /* Calculate objective function. */ 01006 obj = a * b.raise( f ) * c.raise( g ); 01007 return true; 01008 } 01009 01010 /*****************************************************************************/ 01011 /* Gradient evaluation requires 133 flops. */ 01012 /* Reductions possible when b == 1 or c == 1 */ 01013 /*****************************************************************************/ 01014 inline bool g_fcn_3e( double& obj, 01015 Vector3D g_obj[4], 01016 const Vector3D x[4], 01017 const double a, 01018 const Exponent& b, 01019 const Exponent& c ) 01020 { 01021 double matr[9], f; 01022 double adj_m[9], g; 01023 double loc1, loc2, loc3; 01024 01025 /* Calculate M = A*inv(W). */ 01026 f = x[1][0] + x[0][0]; 01027 matr[0] = x[1][0] - x[0][0]; 01028 matr[1] = ( 2.0 * x[2][0] - f ) * isqrt3; 01029 matr[2] = ( 3.0 * x[3][0] - x[2][0] - f ) * isqrt6; 01030 01031 f = x[1][1] + x[0][1]; 01032 matr[3] = x[1][1] - x[0][1]; 01033 matr[4] = ( 2.0 * x[2][1] - f ) * isqrt3; 01034 matr[5] = ( 3.0 * x[3][1] - x[2][1] - f ) * isqrt6; 01035 01036 f = x[1][2] + x[0][2]; 01037 matr[6] = x[1][2] - x[0][2]; 01038 matr[7] = ( 2.0 * x[2][2] - f ) * isqrt3; 01039 matr[8] = ( 3.0 * x[3][2] - x[2][2] - f ) * isqrt6; 01040 01041 /* Calculate det(M). */ 01042 loc1 = matr[4] * matr[8] - matr[5] * matr[7]; 01043 loc2 = matr[5] * matr[6] - matr[3] * matr[8]; 01044 loc3 = matr[3] * matr[7] - matr[4] * matr[6]; 01045 g = matr[0] * loc1 + matr[1] * loc2 + matr[2] * loc3; 01046 if( g < MSQ_MIN ) 01047 { 01048 obj = g; 01049 return false; 01050 } 01051 01052 /* Calculate norm(M). */ 01053 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 01054 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 01055 01056 /* Calculate objective function. */ 01057 obj = a * b.raise( f ) * c.raise( g ); 01058 01059 /* Calculate the derivative of the objective function. */ 01060 f = b.value() * obj / f; /* Constant on nabla f */ 01061 g = c.value() * obj / g; /* Constant on nable g */ 01062 f *= 2.0; /* Modification for nabla f */ 01063 01064 adj_m[0] = matr[0] * f + loc1 * g; 01065 adj_m[1] = matr[1] * f + loc2 * g; 01066 adj_m[2] = matr[2] * f + loc3 * g; 01067 01068 loc1 = matr[0] * g; 01069 loc2 = matr[1] * g; 01070 loc3 = matr[2] * g; 01071 01072 adj_m[3] = matr[3] * f + loc3 * matr[7] - loc2 * matr[8]; 01073 adj_m[4] = matr[4] * f + loc1 * matr[8] - loc3 * matr[6]; 01074 adj_m[5] = matr[5] * f + loc2 * matr[6] - loc1 * matr[7]; 01075 01076 adj_m[6] = matr[6] * f + loc2 * matr[5] - loc3 * matr[4]; 01077 adj_m[7] = matr[7] * f + loc3 * matr[3] - loc1 * matr[5]; 01078 adj_m[8] = matr[8] * f + loc1 * matr[4] - loc2 * matr[3]; 01079 01080 loc1 = isqrt3 * adj_m[1]; 01081 loc2 = isqrt6 * adj_m[2]; 01082 loc3 = loc1 + loc2; 01083 g_obj[0][0] = -adj_m[0] - loc3; 01084 g_obj[1][0] = adj_m[0] - loc3; 01085 g_obj[2][0] = 2.0 * loc1 - loc2; 01086 g_obj[3][0] = 3.0 * loc2; 01087 01088 loc1 = isqrt3 * adj_m[4]; 01089 loc2 = isqrt6 * adj_m[5]; 01090 loc3 = loc1 + loc2; 01091 g_obj[0][1] = -adj_m[3] - loc3; 01092 g_obj[1][1] = adj_m[3] - loc3; 01093 g_obj[2][1] = 2.0 * loc1 - loc2; 01094 g_obj[3][1] = 3.0 * loc2; 01095 01096 loc1 = isqrt3 * adj_m[7]; 01097 loc2 = isqrt6 * adj_m[8]; 01098 loc3 = loc1 + loc2; 01099 g_obj[0][2] = -adj_m[6] - loc3; 01100 g_obj[1][2] = adj_m[6] - loc3; 01101 g_obj[2][2] = 2.0 * loc1 - loc2; 01102 g_obj[3][2] = 3.0 * loc2; 01103 return true; 01104 } 01105 01106 /*****************************************************************************/ 01107 /* Hessian evaluation requires 634 flops. */ 01108 /* Reductions possible when b == 1 or c == 1 */ 01109 /*****************************************************************************/ 01110 inline bool h_fcn_3e( double& obj, 01111 Vector3D g_obj[4], 01112 Matrix3D h_obj[10], 01113 const Vector3D x[4], 01114 const double a, 01115 const Exponent& b, 01116 const Exponent& c ) 01117 { 01118 double matr[9], f; 01119 double adj_m[9], g; 01120 double dg[9], loc0, loc1, loc2, loc3, loc4; 01121 double A[12], J_A[6], J_B[9], J_C[9], cross; 01122 01123 /* Calculate M = A*inv(W). */ 01124 f = x[1][0] + x[0][0]; 01125 matr[0] = x[1][0] - x[0][0]; 01126 matr[1] = ( 2.0 * x[2][0] - f ) * isqrt3; 01127 matr[2] = ( 3.0 * x[3][0] - x[2][0] - f ) * isqrt6; 01128 01129 f = x[1][1] + x[0][1]; 01130 matr[3] = x[1][1] - x[0][1]; 01131 matr[4] = ( 2.0 * x[2][1] - f ) * isqrt3; 01132 matr[5] = ( 3.0 * x[3][1] - x[2][1] - f ) * isqrt6; 01133 01134 f = x[1][2] + x[0][2]; 01135 matr[6] = x[1][2] - x[0][2]; 01136 matr[7] = ( 2.0 * x[2][2] - f ) * isqrt3; 01137 matr[8] = ( 3.0 * x[3][2] - x[2][2] - f ) * isqrt6; 01138 01139 /* Calculate det(M). */ 01140 dg[0] = matr[4] * matr[8] - matr[5] * matr[7]; 01141 dg[1] = matr[5] * matr[6] - matr[3] * matr[8]; 01142 dg[2] = matr[3] * matr[7] - matr[4] * matr[6]; 01143 g = matr[0] * dg[0] + matr[1] * dg[1] + matr[2] * dg[2]; 01144 if( g < MSQ_MIN ) 01145 { 01146 obj = g; 01147 return false; 01148 } 01149 01150 /* Calculate norm(M). */ 01151 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 01152 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 01153 01154 loc3 = f; 01155 loc4 = g; 01156 01157 /* Calculate objective function. */ 01158 obj = a * b.raise( f ) * c.raise( g ); 01159 01160 /* Calculate the derivative of the objective function. */ 01161 f = b.value() * obj / f; /* Constant on nabla f */ 01162 g = c.value() * obj / g; /* Constant on nable g */ 01163 f *= 2.0; /* Modification for nabla f */ 01164 01165 dg[3] = matr[2] * matr[7] - matr[1] * matr[8]; 01166 dg[4] = matr[0] * matr[8] - matr[2] * matr[6]; 01167 dg[5] = matr[1] * matr[6] - matr[0] * matr[7]; 01168 dg[6] = matr[1] * matr[5] - matr[2] * matr[4]; 01169 dg[7] = matr[2] * matr[3] - matr[0] * matr[5]; 01170 dg[8] = matr[0] * matr[4] - matr[1] * matr[3]; 01171 01172 adj_m[0] = matr[0] * f + dg[0] * g; 01173 adj_m[1] = matr[1] * f + dg[1] * g; 01174 adj_m[2] = matr[2] * f + dg[2] * g; 01175 adj_m[3] = matr[3] * f + dg[3] * g; 01176 adj_m[4] = matr[4] * f + dg[4] * g; 01177 adj_m[5] = matr[5] * f + dg[5] * g; 01178 adj_m[6] = matr[6] * f + dg[6] * g; 01179 adj_m[7] = matr[7] * f + dg[7] * g; 01180 adj_m[8] = matr[8] * f + dg[8] * g; 01181 01182 loc0 = isqrt3 * adj_m[1]; 01183 loc1 = isqrt6 * adj_m[2]; 01184 loc2 = loc0 + loc1; 01185 g_obj[0][0] = -adj_m[0] - loc2; 01186 g_obj[1][0] = adj_m[0] - loc2; 01187 g_obj[2][0] = 2.0 * loc0 - loc1; 01188 g_obj[3][0] = 3.0 * loc1; 01189 01190 loc0 = isqrt3 * adj_m[4]; 01191 loc1 = isqrt6 * adj_m[5]; 01192 loc2 = loc0 + loc1; 01193 g_obj[0][1] = -adj_m[3] - loc2; 01194 g_obj[1][1] = adj_m[3] - loc2; 01195 g_obj[2][1] = 2.0 * loc0 - loc1; 01196 g_obj[3][1] = 3.0 * loc1; 01197 01198 loc0 = isqrt3 * adj_m[7]; 01199 loc1 = isqrt6 * adj_m[8]; 01200 loc2 = loc0 + loc1; 01201 g_obj[0][2] = -adj_m[6] - loc2; 01202 g_obj[1][2] = adj_m[6] - loc2; 01203 g_obj[2][2] = 2.0 * loc0 - loc1; 01204 g_obj[3][2] = 3.0 * loc1; 01205 01206 /* Calculate the hessian of the objective. */ 01207 loc0 = f; /* Constant on nabla^2 f */ 01208 loc1 = g; /* Constant on nabla^2 g */ 01209 cross = f * c.value() / loc4; /* Constant on nabla g nabla f */ 01210 f = f * ( b.value() - 1 ) / loc3; /* Constant on nabla f nabla f */ 01211 g = g * ( c.value() - 1 ) / loc4; /* Constant on nabla g nabla g */ 01212 f *= 2.0; /* Modification for nabla f */ 01213 01214 /* First block of rows */ 01215 loc3 = matr[0] * f + dg[0] * cross; 01216 loc4 = dg[0] * g + matr[0] * cross; 01217 01218 J_A[0] = loc0 + loc3 * matr[0] + loc4 * dg[0]; 01219 J_A[1] = loc3 * matr[1] + loc4 * dg[1]; 01220 J_A[2] = loc3 * matr[2] + loc4 * dg[2]; 01221 J_B[0] = loc3 * matr[3] + loc4 * dg[3]; 01222 J_B[1] = loc3 * matr[4] + loc4 * dg[4]; 01223 J_B[2] = loc3 * matr[5] + loc4 * dg[5]; 01224 J_C[0] = loc3 * matr[6] + loc4 * dg[6]; 01225 J_C[1] = loc3 * matr[7] + loc4 * dg[7]; 01226 J_C[2] = loc3 * matr[8] + loc4 * dg[8]; 01227 01228 loc3 = matr[1] * f + dg[1] * cross; 01229 loc4 = dg[1] * g + matr[1] * cross; 01230 01231 J_A[3] = loc0 + loc3 * matr[1] + loc4 * dg[1]; 01232 J_A[4] = loc3 * matr[2] + loc4 * dg[2]; 01233 J_B[3] = loc3 * matr[3] + loc4 * dg[3]; 01234 J_B[4] = loc3 * matr[4] + loc4 * dg[4]; 01235 J_B[5] = loc3 * matr[5] + loc4 * dg[5]; 01236 J_C[3] = loc3 * matr[6] + loc4 * dg[6]; 01237 J_C[4] = loc3 * matr[7] + loc4 * dg[7]; 01238 J_C[5] = loc3 * matr[8] + loc4 * dg[8]; 01239 01240 loc3 = matr[2] * f + dg[2] * cross; 01241 loc4 = dg[2] * g + matr[2] * cross; 01242 01243 J_A[5] = loc0 + loc3 * matr[2] + loc4 * dg[2]; 01244 J_B[6] = loc3 * matr[3] + loc4 * dg[3]; 01245 J_B[7] = loc3 * matr[4] + loc4 * dg[4]; 01246 J_B[8] = loc3 * matr[5] + loc4 * dg[5]; 01247 J_C[6] = loc3 * matr[6] + loc4 * dg[6]; 01248 J_C[7] = loc3 * matr[7] + loc4 * dg[7]; 01249 J_C[8] = loc3 * matr[8] + loc4 * dg[8]; 01250 01251 /* First diagonal block */ 01252 loc2 = isqrt3 * J_A[1]; 01253 loc3 = isqrt6 * J_A[2]; 01254 loc4 = loc2 + loc3; 01255 01256 A[0] = -J_A[0] - loc4; 01257 A[1] = J_A[0] - loc4; 01258 01259 loc2 = isqrt3 * J_A[3]; 01260 loc3 = isqrt6 * J_A[4]; 01261 loc4 = loc2 + loc3; 01262 01263 A[4] = -J_A[1] - loc4; 01264 A[5] = J_A[1] - loc4; 01265 A[6] = 2.0 * loc2 - loc3; 01266 01267 loc2 = isqrt3 * J_A[4]; 01268 loc3 = isqrt6 * J_A[5]; 01269 loc4 = loc2 + loc3; 01270 01271 A[8] = -J_A[2] - loc4; 01272 A[9] = J_A[2] - loc4; 01273 A[10] = 2.0 * loc2 - loc3; 01274 A[11] = 3.0 * loc3; 01275 01276 loc2 = isqrt3 * A[4]; 01277 loc3 = isqrt6 * A[8]; 01278 loc4 = loc2 + loc3; 01279 01280 h_obj[0][0][0] = -A[0] - loc4; 01281 h_obj[1][0][0] = A[0] - loc4; 01282 h_obj[2][0][0] = 2.0 * loc2 - loc3; 01283 h_obj[3][0][0] = 3.0 * loc3; 01284 01285 loc2 = isqrt3 * A[5]; 01286 loc3 = isqrt6 * A[9]; 01287 01288 h_obj[4][0][0] = A[1] - loc2 - loc3; 01289 h_obj[5][0][0] = 2.0 * loc2 - loc3; 01290 h_obj[6][0][0] = 3.0 * loc3; 01291 01292 loc3 = isqrt6 * A[10]; 01293 h_obj[7][0][0] = tisqrt3 * A[6] - loc3; 01294 h_obj[8][0][0] = 3.0 * loc3; 01295 01296 h_obj[9][0][0] = tisqrt6 * A[11]; 01297 01298 /* First off-diagonal block */ 01299 loc2 = matr[8] * loc1; 01300 J_B[1] += loc2; 01301 J_B[3] -= loc2; 01302 01303 loc2 = matr[7] * loc1; 01304 J_B[2] -= loc2; 01305 J_B[6] += loc2; 01306 01307 loc2 = matr[6] * loc1; 01308 J_B[5] += loc2; 01309 J_B[7] -= loc2; 01310 01311 loc2 = isqrt3 * J_B[3]; 01312 loc3 = isqrt6 * J_B[6]; 01313 loc4 = loc2 + loc3; 01314 01315 A[0] = -J_B[0] - loc4; 01316 A[1] = J_B[0] - loc4; 01317 A[2] = 2.0 * loc2 - loc3; 01318 A[3] = 3.0 * loc3; 01319 01320 loc2 = isqrt3 * J_B[4]; 01321 loc3 = isqrt6 * J_B[7]; 01322 loc4 = loc2 + loc3; 01323 01324 A[4] = -J_B[1] - loc4; 01325 A[5] = J_B[1] - loc4; 01326 A[6] = 2.0 * loc2 - loc3; 01327 A[7] = 3.0 * loc3; 01328 01329 loc2 = isqrt3 * J_B[5]; 01330 loc3 = isqrt6 * J_B[8]; 01331 loc4 = loc2 + loc3; 01332 01333 A[8] = -J_B[2] - loc4; 01334 A[9] = J_B[2] - loc4; 01335 A[10] = 2.0 * loc2 - loc3; 01336 A[11] = 3.0 * loc3; 01337 01338 loc2 = isqrt3 * A[4]; 01339 loc3 = isqrt6 * A[8]; 01340 loc4 = loc2 + loc3; 01341 01342 h_obj[0][0][1] = -A[0] - loc4; 01343 h_obj[1][0][1] = A[0] - loc4; 01344 h_obj[2][0][1] = 2.0 * loc2 - loc3; 01345 h_obj[3][0][1] = 3.0 * loc3; 01346 01347 loc2 = isqrt3 * A[5]; 01348 loc3 = isqrt6 * A[9]; 01349 loc4 = loc2 + loc3; 01350 01351 h_obj[1][1][0] = -A[1] - loc4; 01352 h_obj[4][0][1] = A[1] - loc4; 01353 h_obj[5][0][1] = 2.0 * loc2 - loc3; 01354 h_obj[6][0][1] = 3.0 * loc3; 01355 01356 loc2 = isqrt3 * A[6]; 01357 loc3 = isqrt6 * A[10]; 01358 loc4 = loc2 + loc3; 01359 01360 h_obj[2][1][0] = -A[2] - loc4; 01361 h_obj[5][1][0] = A[2] - loc4; 01362 h_obj[7][0][1] = 2.0 * loc2 - loc3; 01363 h_obj[8][0][1] = 3.0 * loc3; 01364 01365 loc2 = isqrt3 * A[7]; 01366 loc3 = isqrt6 * A[11]; 01367 loc4 = loc2 + loc3; 01368 01369 h_obj[3][1][0] = -A[3] - loc4; 01370 h_obj[6][1][0] = A[3] - loc4; 01371 h_obj[8][1][0] = 2.0 * loc2 - loc3; 01372 h_obj[9][0][1] = 3.0 * loc3; 01373 01374 /* Second off-diagonal block */ 01375 loc2 = matr[5] * loc1; 01376 J_C[1] -= loc2; 01377 J_C[3] += loc2; 01378 01379 loc2 = matr[4] * loc1; 01380 J_C[2] += loc2; 01381 J_C[6] -= loc2; 01382 01383 loc2 = matr[3] * loc1; 01384 J_C[5] -= loc2; 01385 J_C[7] += loc2; 01386 01387 loc2 = isqrt3 * J_C[3]; 01388 loc3 = isqrt6 * J_C[6]; 01389 loc4 = loc2 + loc3; 01390 01391 A[0] = -J_C[0] - loc4; 01392 A[1] = J_C[0] - loc4; 01393 A[2] = 2.0 * loc2 - loc3; 01394 A[3] = 3.0 * loc3; 01395 01396 loc2 = isqrt3 * J_C[4]; 01397 loc3 = isqrt6 * J_C[7]; 01398 loc4 = loc2 + loc3; 01399 01400 A[4] = -J_C[1] - loc4; 01401 A[5] = J_C[1] - loc4; 01402 A[6] = 2.0 * loc2 - loc3; 01403 A[7] = 3.0 * loc3; 01404 01405 loc2 = isqrt3 * J_C[5]; 01406 loc3 = isqrt6 * J_C[8]; 01407 loc4 = loc2 + loc3; 01408 01409 A[8] = -J_C[2] - loc4; 01410 A[9] = J_C[2] - loc4; 01411 A[10] = 2.0 * loc2 - loc3; 01412 A[11] = 3.0 * loc3; 01413 01414 loc2 = isqrt3 * A[4]; 01415 loc3 = isqrt6 * A[8]; 01416 loc4 = loc2 + loc3; 01417 01418 h_obj[0][0][2] = -A[0] - loc4; 01419 h_obj[1][0][2] = A[0] - loc4; 01420 h_obj[2][0][2] = 2.0 * loc2 - loc3; 01421 h_obj[3][0][2] = 3.0 * loc3; 01422 01423 loc2 = isqrt3 * A[5]; 01424 loc3 = isqrt6 * A[9]; 01425 loc4 = loc2 + loc3; 01426 01427 h_obj[1][2][0] = -A[1] - loc4; 01428 h_obj[4][0][2] = A[1] - loc4; 01429 h_obj[5][0][2] = 2.0 * loc2 - loc3; 01430 h_obj[6][0][2] = 3.0 * loc3; 01431 01432 loc2 = isqrt3 * A[6]; 01433 loc3 = isqrt6 * A[10]; 01434 loc4 = loc2 + loc3; 01435 01436 h_obj[2][2][0] = -A[2] - loc4; 01437 h_obj[5][2][0] = A[2] - loc4; 01438 h_obj[7][0][2] = 2.0 * loc2 - loc3; 01439 h_obj[8][0][2] = 3.0 * loc3; 01440 01441 loc2 = isqrt3 * A[7]; 01442 loc3 = isqrt6 * A[11]; 01443 loc4 = loc2 + loc3; 01444 01445 h_obj[3][2][0] = -A[3] - loc4; 01446 h_obj[6][2][0] = A[3] - loc4; 01447 h_obj[8][2][0] = 2.0 * loc2 - loc3; 01448 h_obj[9][0][2] = 3.0 * loc3; 01449 01450 /* Second block of rows */ 01451 loc3 = matr[3] * f + dg[3] * cross; 01452 loc4 = dg[3] * g + matr[3] * cross; 01453 01454 J_A[0] = loc0 + loc3 * matr[3] + loc4 * dg[3]; 01455 J_A[1] = loc3 * matr[4] + loc4 * dg[4]; 01456 J_A[2] = loc3 * matr[5] + loc4 * dg[5]; 01457 J_B[0] = loc3 * matr[6] + loc4 * dg[6]; 01458 J_B[1] = loc3 * matr[7] + loc4 * dg[7]; 01459 J_B[2] = loc3 * matr[8] + loc4 * dg[8]; 01460 01461 loc3 = matr[4] * f + dg[4] * cross; 01462 loc4 = dg[4] * g + matr[4] * cross; 01463 01464 J_A[3] = loc0 + loc3 * matr[4] + loc4 * dg[4]; 01465 J_A[4] = loc3 * matr[5] + loc4 * dg[5]; 01466 J_B[3] = loc3 * matr[6] + loc4 * dg[6]; 01467 J_B[4] = loc3 * matr[7] + loc4 * dg[7]; 01468 J_B[5] = loc3 * matr[8] + loc4 * dg[8]; 01469 01470 loc3 = matr[5] * f + dg[5] * cross; 01471 loc4 = dg[5] * g + matr[5] * cross; 01472 01473 J_A[5] = loc0 + loc3 * matr[5] + loc4 * dg[5]; 01474 J_B[6] = loc3 * matr[6] + loc4 * dg[6]; 01475 J_B[7] = loc3 * matr[7] + loc4 * dg[7]; 01476 J_B[8] = loc3 * matr[8] + loc4 * dg[8]; 01477 01478 /* Second diagonal block */ 01479 loc2 = isqrt3 * J_A[1]; 01480 loc3 = isqrt6 * J_A[2]; 01481 loc4 = loc2 + loc3; 01482 01483 A[0] = -J_A[0] - loc4; 01484 A[1] = J_A[0] - loc4; 01485 01486 loc2 = isqrt3 * J_A[3]; 01487 loc3 = isqrt6 * J_A[4]; 01488 loc4 = loc2 + loc3; 01489 01490 A[4] = -J_A[1] - loc4; 01491 A[5] = J_A[1] - loc4; 01492 A[6] = 2.0 * loc2 - loc3; 01493 01494 loc2 = isqrt3 * J_A[4]; 01495 loc3 = isqrt6 * J_A[5]; 01496 loc4 = loc2 + loc3; 01497 01498 A[8] = -J_A[2] - loc4; 01499 A[9] = J_A[2] - loc4; 01500 A[10] = 2.0 * loc2 - loc3; 01501 A[11] = 3.0 * loc3; 01502 01503 loc2 = isqrt3 * A[4]; 01504 loc3 = isqrt6 * A[8]; 01505 loc4 = loc2 + loc3; 01506 01507 h_obj[0][1][1] = -A[0] - loc4; 01508 h_obj[1][1][1] = A[0] - loc4; 01509 h_obj[2][1][1] = 2.0 * loc2 - loc3; 01510 h_obj[3][1][1] = 3.0 * loc3; 01511 01512 loc2 = isqrt3 * A[5]; 01513 loc3 = isqrt6 * A[9]; 01514 01515 h_obj[4][1][1] = A[1] - loc2 - loc3; 01516 h_obj[5][1][1] = 2.0 * loc2 - loc3; 01517 h_obj[6][1][1] = 3.0 * loc3; 01518 01519 loc3 = isqrt6 * A[10]; 01520 h_obj[7][1][1] = tisqrt3 * A[6] - loc3; 01521 h_obj[8][1][1] = 3.0 * loc3; 01522 01523 h_obj[9][1][1] = tisqrt6 * A[11]; 01524 01525 /* Third off-diagonal block */ 01526 loc2 = matr[2] * loc1; 01527 J_B[1] += loc2; 01528 J_B[3] -= loc2; 01529 01530 loc2 = matr[1] * loc1; 01531 J_B[2] -= loc2; 01532 J_B[6] += loc2; 01533 01534 loc2 = matr[0] * loc1; 01535 J_B[5] += loc2; 01536 J_B[7] -= loc2; 01537 01538 loc2 = isqrt3 * J_B[3]; 01539 loc3 = isqrt6 * J_B[6]; 01540 loc4 = loc2 + loc3; 01541 01542 A[0] = -J_B[0] - loc4; 01543 A[1] = J_B[0] - loc4; 01544 A[2] = 2.0 * loc2 - loc3; 01545 A[3] = 3.0 * loc3; 01546 01547 loc2 = isqrt3 * J_B[4]; 01548 loc3 = isqrt6 * J_B[7]; 01549 loc4 = loc2 + loc3; 01550 01551 A[4] = -J_B[1] - loc4; 01552 A[5] = J_B[1] - loc4; 01553 A[6] = 2.0 * loc2 - loc3; 01554 A[7] = 3.0 * loc3; 01555 01556 loc2 = isqrt3 * J_B[5]; 01557 loc3 = isqrt6 * J_B[8]; 01558 loc4 = loc2 + loc3; 01559 01560 A[8] = -J_B[2] - loc4; 01561 A[9] = J_B[2] - loc4; 01562 A[10] = 2.0 * loc2 - loc3; 01563 A[11] = 3.0 * loc3; 01564 01565 loc2 = isqrt3 * A[4]; 01566 loc3 = isqrt6 * A[8]; 01567 loc4 = loc2 + loc3; 01568 01569 h_obj[0][1][2] = -A[0] - loc4; 01570 h_obj[1][1][2] = A[0] - loc4; 01571 h_obj[2][1][2] = 2.0 * loc2 - loc3; 01572 h_obj[3][1][2] = 3.0 * loc3; 01573 01574 loc2 = isqrt3 * A[5]; 01575 loc3 = isqrt6 * A[9]; 01576 loc4 = loc2 + loc3; 01577 01578 h_obj[1][2][1] = -A[1] - loc4; 01579 h_obj[4][1][2] = A[1] - loc4; 01580 h_obj[5][1][2] = 2.0 * loc2 - loc3; 01581 h_obj[6][1][2] = 3.0 * loc3; 01582 01583 loc2 = isqrt3 * A[6]; 01584 loc3 = isqrt6 * A[10]; 01585 loc4 = loc2 + loc3; 01586 01587 h_obj[2][2][1] = -A[2] - loc4; 01588 h_obj[5][2][1] = A[2] - loc4; 01589 h_obj[7][1][2] = 2.0 * loc2 - loc3; 01590 h_obj[8][1][2] = 3.0 * loc3; 01591 01592 loc2 = isqrt3 * A[7]; 01593 loc3 = isqrt6 * A[11]; 01594 loc4 = loc2 + loc3; 01595 01596 h_obj[3][2][1] = -A[3] - loc4; 01597 h_obj[6][2][1] = A[3] - loc4; 01598 h_obj[8][2][1] = 2.0 * loc2 - loc3; 01599 h_obj[9][1][2] = 3.0 * loc3; 01600 01601 /* Third block of rows */ 01602 loc3 = matr[6] * f + dg[6] * cross; 01603 loc4 = dg[6] * g + matr[6] * cross; 01604 01605 J_A[0] = loc0 + loc3 * matr[6] + loc4 * dg[6]; 01606 J_A[1] = loc3 * matr[7] + loc4 * dg[7]; 01607 J_A[2] = loc3 * matr[8] + loc4 * dg[8]; 01608 01609 loc3 = matr[7] * f + dg[7] * cross; 01610 loc4 = dg[7] * g + matr[7] * cross; 01611 01612 J_A[3] = loc0 + loc3 * matr[7] + loc4 * dg[7]; 01613 J_A[4] = loc3 * matr[8] + loc4 * dg[8]; 01614 01615 loc3 = matr[8] * f + dg[8] * cross; 01616 loc4 = dg[8] * g + matr[8] * cross; 01617 01618 J_A[5] = loc0 + loc3 * matr[8] + loc4 * dg[8]; 01619 01620 /* Third diagonal block */ 01621 loc2 = isqrt3 * J_A[1]; 01622 loc3 = isqrt6 * J_A[2]; 01623 loc4 = loc2 + loc3; 01624 01625 A[0] = -J_A[0] - loc4; 01626 A[1] = J_A[0] - loc4; 01627 01628 loc2 = isqrt3 * J_A[3]; 01629 loc3 = isqrt6 * J_A[4]; 01630 loc4 = loc2 + loc3; 01631 01632 A[4] = -J_A[1] - loc4; 01633 A[5] = J_A[1] - loc4; 01634 A[6] = 2.0 * loc2 - loc3; 01635 01636 loc2 = isqrt3 * J_A[4]; 01637 loc3 = isqrt6 * J_A[5]; 01638 loc4 = loc2 + loc3; 01639 01640 A[8] = -J_A[2] - loc4; 01641 A[9] = J_A[2] - loc4; 01642 A[10] = 2.0 * loc2 - loc3; 01643 A[11] = 3.0 * loc3; 01644 01645 loc2 = isqrt3 * A[4]; 01646 loc3 = isqrt6 * A[8]; 01647 loc4 = loc2 + loc3; 01648 01649 h_obj[0][2][2] = -A[0] - loc4; 01650 h_obj[1][2][2] = A[0] - loc4; 01651 h_obj[2][2][2] = 2.0 * loc2 - loc3; 01652 h_obj[3][2][2] = 3.0 * loc3; 01653 01654 loc2 = isqrt3 * A[5]; 01655 loc3 = isqrt6 * A[9]; 01656 01657 h_obj[4][2][2] = A[1] - loc2 - loc3; 01658 h_obj[5][2][2] = 2.0 * loc2 - loc3; 01659 h_obj[6][2][2] = 3.0 * loc3; 01660 01661 loc3 = isqrt6 * A[10]; 01662 h_obj[7][2][2] = tisqrt3 * A[6] - loc3; 01663 h_obj[8][2][2] = 3.0 * loc3; 01664 01665 h_obj[9][2][2] = tisqrt6 * A[11]; 01666 01667 // completes diagonal blocks. 01668 h_obj[0].fill_lower_triangle(); 01669 h_obj[4].fill_lower_triangle(); 01670 h_obj[7].fill_lower_triangle(); 01671 h_obj[9].fill_lower_triangle(); 01672 return true; 01673 } 01674 01675 /*****************************************************************************/ 01676 /* The following set of functions reference tetrahedral elements to a */ 01677 /* equilateral tetrahedron. These functions are specialized toward */ 01678 /* obtaining the gradient and Hessian with respect to a single vertex. */ 01679 /*****************************************************************************/ 01680 01681 inline bool g_fcn_3e_v3( double& obj, 01682 Vector3D& g_obj, 01683 const Vector3D x[4], 01684 const double a, 01685 const Exponent& b, 01686 const Exponent& c ) 01687 { 01688 double matr[9], f, g; 01689 double loc1, loc2, loc3; 01690 01691 /* Calculate M = A*inv(W). */ 01692 f = x[1][0] + x[0][0]; 01693 matr[0] = x[1][0] - x[0][0]; 01694 matr[1] = ( 2.0 * x[2][0] - f ) * isqrt3; 01695 matr[2] = ( 3.0 * x[3][0] - x[2][0] - f ) * isqrt6; 01696 01697 f = x[1][1] + x[0][1]; 01698 matr[3] = x[1][1] - x[0][1]; 01699 matr[4] = ( 2.0 * x[2][1] - f ) * isqrt3; 01700 matr[5] = ( 3.0 * x[3][1] - x[2][1] - f ) * isqrt6; 01701 01702 f = x[1][2] + x[0][2]; 01703 matr[6] = x[1][2] - x[0][2]; 01704 matr[7] = ( 2.0 * x[2][2] - f ) * isqrt3; 01705 matr[8] = ( 3.0 * x[3][2] - x[2][2] - f ) * isqrt6; 01706 01707 /* Calculate det(M). */ 01708 loc1 = matr[4] * matr[8] - matr[5] * matr[7]; 01709 loc2 = matr[5] * matr[6] - matr[3] * matr[8]; 01710 loc3 = matr[3] * matr[7] - matr[4] * matr[6]; 01711 g = matr[0] * loc1 + matr[1] * loc2 + matr[2] * loc3; 01712 if( g < MSQ_MIN ) 01713 { 01714 obj = g; 01715 return false; 01716 } 01717 01718 /* Calculate norm(M). */ 01719 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 01720 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 01721 01722 /* Calculate objective function. */ 01723 obj = a * b.raise( f ) * c.raise( g ); 01724 01725 /* Calculate the derivative of the objective function. */ 01726 f = b.value() * obj / f; /* Constant on nabla f */ 01727 g = c.value() * obj / g; /* Constant on nable g */ 01728 f *= 2.0; /* Modification for nabla f */ 01729 01730 g_obj[0] = tisqrt6 * ( matr[2] * f + loc3 * g ); 01731 01732 loc1 = matr[0] * g; 01733 loc2 = matr[1] * g; 01734 01735 g_obj[1] = tisqrt6 * ( matr[5] * f + loc2 * matr[6] - loc1 * matr[7] ); 01736 g_obj[2] = tisqrt6 * ( matr[8] * f + loc1 * matr[4] - loc2 * matr[3] ); 01737 return true; 01738 } 01739 01740 inline bool g_fcn_3e_v0( double& obj, 01741 Vector3D& g_obj, 01742 const Vector3D x[4], 01743 const double a, 01744 const Exponent& b, 01745 const Exponent& c ) 01746 { 01747 static Vector3D my_x[4]; 01748 01749 my_x[0] = x[1]; 01750 my_x[1] = x[3]; 01751 my_x[2] = x[2]; 01752 my_x[3] = x[0]; 01753 return g_fcn_3e_v3( obj, g_obj, my_x, a, b, c ); 01754 } 01755 01756 inline bool g_fcn_3e_v1( double& obj, 01757 Vector3D& g_obj, 01758 const Vector3D x[4], 01759 const double a, 01760 const Exponent& b, 01761 const Exponent& c ) 01762 { 01763 static Vector3D my_x[4]; 01764 01765 my_x[0] = x[0]; 01766 my_x[1] = x[2]; 01767 my_x[2] = x[3]; 01768 my_x[3] = x[1]; 01769 return g_fcn_3e_v3( obj, g_obj, my_x, a, b, c ); 01770 } 01771 01772 inline bool g_fcn_3e_v2( double& obj, 01773 Vector3D& g_obj, 01774 const Vector3D x[4], 01775 const double a, 01776 const Exponent& b, 01777 const Exponent& c ) 01778 { 01779 static Vector3D my_x[4]; 01780 01781 my_x[0] = x[1]; 01782 my_x[1] = x[0]; 01783 my_x[2] = x[3]; 01784 my_x[3] = x[2]; 01785 return g_fcn_3e_v3( obj, g_obj, my_x, a, b, c ); 01786 } 01787 01788 inline bool h_fcn_3e_v3( double& obj, 01789 Vector3D& g_obj, 01790 Matrix3D& h_obj, 01791 const Vector3D x[4], 01792 const double a, 01793 const Exponent& b, 01794 const Exponent& c ) 01795 { 01796 double matr[9], f, g; 01797 double dg[9], loc0, /*loc1,*/ loc3, loc4; 01798 double cross; 01799 01800 /* Calculate M = A*inv(W). */ 01801 f = x[1][0] + x[0][0]; 01802 matr[0] = x[1][0] - x[0][0]; 01803 matr[1] = ( 2.0 * x[2][0] - f ) * isqrt3; 01804 matr[2] = ( 3.0 * x[3][0] - x[2][0] - f ) * isqrt6; 01805 01806 f = x[1][1] + x[0][1]; 01807 matr[3] = x[1][1] - x[0][1]; 01808 matr[4] = ( 2.0 * x[2][1] - f ) * isqrt3; 01809 matr[5] = ( 3.0 * x[3][1] - x[2][1] - f ) * isqrt6; 01810 01811 f = x[1][2] + x[0][2]; 01812 matr[6] = x[1][2] - x[0][2]; 01813 matr[7] = ( 2.0 * x[2][2] - f ) * isqrt3; 01814 matr[8] = ( 3.0 * x[3][2] - x[2][2] - f ) * isqrt6; 01815 01816 /* Calculate det(M). */ 01817 dg[0] = matr[4] * matr[8] - matr[5] * matr[7]; 01818 dg[1] = matr[5] * matr[6] - matr[3] * matr[8]; 01819 dg[2] = matr[3] * matr[7] - matr[4] * matr[6]; 01820 g = matr[0] * dg[0] + matr[1] * dg[1] + matr[2] * dg[2]; 01821 if( g < MSQ_MIN ) 01822 { 01823 obj = g; 01824 return false; 01825 } 01826 01827 /* Calculate norm(M). */ 01828 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 01829 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 01830 01831 loc3 = f; 01832 loc4 = g; 01833 01834 /* Calculate objective function. */ 01835 obj = a * b.raise( f ) * c.raise( g ); 01836 01837 /* Calculate the derivative of the objective function. */ 01838 f = b.value() * obj / f; /* Constant on nabla f */ 01839 g = c.value() * obj / g; /* Constant on nable g */ 01840 f *= 2.0; /* Modification for nabla f */ 01841 01842 dg[5] = matr[1] * matr[6] - matr[0] * matr[7]; 01843 dg[8] = matr[0] * matr[4] - matr[1] * matr[3]; 01844 01845 g_obj[0] = tisqrt6 * ( matr[2] * f + dg[2] * g ); 01846 g_obj[1] = tisqrt6 * ( matr[5] * f + dg[5] * g ); 01847 g_obj[2] = tisqrt6 * ( matr[8] * f + dg[8] * g ); 01848 01849 /* Calculate the hessian of the objective. */ 01850 loc0 = f; /* Constant on nabla^2 f */ 01851 // loc1 = g; /* Constant on nabla^2 g */ 01852 cross = f * c.value() / loc4; /* Constant on nabla g nabla f */ 01853 f = f * ( b.value() - 1 ) / loc3; /* Constant on nabla f nabla f */ 01854 g = g * ( c.value() - 1 ) / loc4; /* Constant on nabla g nabla g */ 01855 f *= 2.0; /* Modification for nabla f */ 01856 01857 /* First block of rows */ 01858 loc3 = matr[2] * f + dg[2] * cross; 01859 loc4 = dg[2] * g + matr[2] * cross; 01860 01861 h_obj[0][0] = 1.5 * ( loc0 + loc3 * matr[2] + loc4 * dg[2] ); 01862 h_obj[0][1] = 1.5 * ( loc3 * matr[5] + loc4 * dg[5] ); 01863 h_obj[0][2] = 1.5 * ( loc3 * matr[8] + loc4 * dg[8] ); 01864 01865 /* Second block of rows */ 01866 loc3 = matr[5] * f + dg[5] * cross; 01867 loc4 = dg[5] * g + matr[5] * cross; 01868 01869 h_obj[1][1] = 1.5 * ( loc0 + loc3 * matr[5] + loc4 * dg[5] ); 01870 h_obj[1][2] = 1.5 * ( loc3 * matr[8] + loc4 * dg[8] ); 01871 01872 /* Third block of rows */ 01873 loc3 = matr[8] * f + dg[8] * cross; 01874 loc4 = dg[8] * g + matr[8] * cross; 01875 01876 h_obj[2][2] = 1.5 * ( loc0 + loc3 * matr[8] + loc4 * dg[8] ); 01877 01878 // completes diagonal block. 01879 h_obj.fill_lower_triangle(); 01880 return true; 01881 } 01882 01883 inline bool h_fcn_3e_v0( double& obj, 01884 Vector3D& g_obj, 01885 Matrix3D& h_obj, 01886 const Vector3D x[4], 01887 const double a, 01888 const Exponent& b, 01889 const Exponent& c ) 01890 { 01891 static Vector3D my_x[4]; 01892 01893 my_x[0] = x[1]; 01894 my_x[1] = x[3]; 01895 my_x[2] = x[2]; 01896 my_x[3] = x[0]; 01897 return h_fcn_3e_v3( obj, g_obj, h_obj, my_x, a, b, c ); 01898 } 01899 01900 inline bool h_fcn_3e_v1( double& obj, 01901 Vector3D& g_obj, 01902 Matrix3D& h_obj, 01903 const Vector3D x[4], 01904 const double a, 01905 const Exponent& b, 01906 const Exponent& c ) 01907 { 01908 static Vector3D my_x[4]; 01909 01910 my_x[0] = x[0]; 01911 my_x[1] = x[2]; 01912 my_x[2] = x[3]; 01913 my_x[3] = x[1]; 01914 return h_fcn_3e_v3( obj, g_obj, h_obj, my_x, a, b, c ); 01915 } 01916 01917 inline bool h_fcn_3e_v2( double& obj, 01918 Vector3D& g_obj, 01919 Matrix3D& h_obj, 01920 const Vector3D x[4], 01921 const double a, 01922 const Exponent& b, 01923 const Exponent& c ) 01924 { 01925 static Vector3D my_x[4]; 01926 01927 my_x[0] = x[1]; 01928 my_x[1] = x[0]; 01929 my_x[2] = x[3]; 01930 my_x[3] = x[2]; 01931 return h_fcn_3e_v3( obj, g_obj, h_obj, my_x, a, b, c ); 01932 } 01933 01934 /*****************************************************************************/ 01935 /* The following set of functions reference tetrahedral elements to a */ 01936 /* right tetrahedron. They are used when assessing the quality of a */ 01937 /* hexahedral element. A zero return value indicates success, while */ 01938 /* a nonzero value indicates failure. */ 01939 /*****************************************************************************/ 01940 01941 /*****************************************************************************/ 01942 /* Function evaluation requires 53 flops. */ 01943 /* Reductions possible when b == 1, c == 1, or d == 1 */ 01944 /*****************************************************************************/ 01945 inline bool m_fcn_3i( double& obj, 01946 const Vector3D x[4], 01947 const double a, 01948 const Exponent& b, 01949 const Exponent& c, 01950 const Vector3D& d ) 01951 { 01952 double matr[9], f; 01953 double g; 01954 01955 /* Calculate M = A*inv(W). */ 01956 matr[0] = d[0] * ( x[1][0] - x[0][0] ); 01957 matr[1] = d[1] * ( x[2][0] - x[0][0] ); 01958 matr[2] = d[2] * ( x[3][0] - x[0][0] ); 01959 01960 matr[3] = d[0] * ( x[1][1] - x[0][1] ); 01961 matr[4] = d[1] * ( x[2][1] - x[0][1] ); 01962 matr[5] = d[2] * ( x[3][1] - x[0][1] ); 01963 01964 matr[6] = d[0] * ( x[1][2] - x[0][2] ); 01965 matr[7] = d[1] * ( x[2][2] - x[0][2] ); 01966 matr[8] = d[2] * ( x[3][2] - x[0][2] ); 01967 01968 /* Calculate det(M). */ 01969 g = matr[0] * ( matr[4] * matr[8] - matr[5] * matr[7] ) + matr[1] * ( matr[5] * matr[6] - matr[3] * matr[8] ) + 01970 matr[2] * ( matr[3] * matr[7] - matr[4] * matr[6] ); 01971 if( g < MSQ_MIN ) 01972 { 01973 obj = g; 01974 return false; 01975 } 01976 01977 /* Calculate norm(M). */ 01978 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 01979 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 01980 01981 /* Calculate objective function. */ 01982 obj = a * b.raise( f ) * c.raise( g ); 01983 return true; 01984 } 01985 01986 /*****************************************************************************/ 01987 /* Gradient evaluation requires 115 flops. */ 01988 /* Reductions possible when b == 1, c == 1, or d == 1 */ 01989 /*****************************************************************************/ 01990 inline bool g_fcn_3i( double& obj, 01991 Vector3D g_obj[4], 01992 const Vector3D x[4], 01993 const double a, 01994 const Exponent& b, 01995 const Exponent& c, 01996 const Vector3D& d ) 01997 { 01998 double matr[9], f; 01999 double adj_m[9], g; 02000 double loc1, loc2, loc3; 02001 02002 /* Calculate M = A*inv(W). */ 02003 matr[0] = d[0] * ( x[1][0] - x[0][0] ); 02004 matr[1] = d[1] * ( x[2][0] - x[0][0] ); 02005 matr[2] = d[2] * ( x[3][0] - x[0][0] ); 02006 02007 matr[3] = d[0] * ( x[1][1] - x[0][1] ); 02008 matr[4] = d[1] * ( x[2][1] - x[0][1] ); 02009 matr[5] = d[2] * ( x[3][1] - x[0][1] ); 02010 02011 matr[6] = d[0] * ( x[1][2] - x[0][2] ); 02012 matr[7] = d[1] * ( x[2][2] - x[0][2] ); 02013 matr[8] = d[2] * ( x[3][2] - x[0][2] ); 02014 02015 /* Calculate det(M). */ 02016 loc1 = matr[4] * matr[8] - matr[5] * matr[7]; 02017 loc2 = matr[5] * matr[6] - matr[3] * matr[8]; 02018 loc3 = matr[3] * matr[7] - matr[4] * matr[6]; 02019 g = matr[0] * loc1 + matr[1] * loc2 + matr[2] * loc3; 02020 if( g < MSQ_MIN ) 02021 { 02022 obj = g; 02023 return false; 02024 } 02025 02026 /* Calculate norm(M). */ 02027 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 02028 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 02029 02030 /* Calculate objective function. */ 02031 obj = a * b.raise( f ) * c.raise( g ); 02032 02033 /* Calculate the derivative of the objective function. */ 02034 f = b.value() * obj / f; /* Constant on nabla f */ 02035 g = c.value() * obj / g; /* Constant on nable g */ 02036 f *= 2.0; /* Modification for nabla f */ 02037 02038 adj_m[0] = d[0] * ( matr[0] * f + loc1 * g ); 02039 adj_m[1] = d[1] * ( matr[1] * f + loc2 * g ); 02040 adj_m[2] = d[2] * ( matr[2] * f + loc3 * g ); 02041 02042 loc1 = matr[0] * g; 02043 loc2 = matr[1] * g; 02044 loc3 = matr[2] * g; 02045 02046 adj_m[3] = d[0] * ( matr[3] * f + loc3 * matr[7] - loc2 * matr[8] ); 02047 adj_m[4] = d[1] * ( matr[4] * f + loc1 * matr[8] - loc3 * matr[6] ); 02048 adj_m[5] = d[2] * ( matr[5] * f + loc2 * matr[6] - loc1 * matr[7] ); 02049 02050 adj_m[6] = d[0] * ( matr[6] * f + loc2 * matr[5] - loc3 * matr[4] ); 02051 adj_m[7] = d[1] * ( matr[7] * f + loc3 * matr[3] - loc1 * matr[5] ); 02052 adj_m[8] = d[2] * ( matr[8] * f + loc1 * matr[4] - loc2 * matr[3] ); 02053 02054 g_obj[0][0] = -adj_m[0] - adj_m[1] - adj_m[2]; 02055 g_obj[1][0] = adj_m[0]; 02056 g_obj[2][0] = adj_m[1]; 02057 g_obj[3][0] = adj_m[2]; 02058 02059 g_obj[0][1] = -adj_m[3] - adj_m[4] - adj_m[5]; 02060 g_obj[1][1] = adj_m[3]; 02061 g_obj[2][1] = adj_m[4]; 02062 g_obj[3][1] = adj_m[5]; 02063 02064 g_obj[0][2] = -adj_m[6] - adj_m[7] - adj_m[8]; 02065 g_obj[1][2] = adj_m[6]; 02066 g_obj[2][2] = adj_m[7]; 02067 g_obj[3][2] = adj_m[8]; 02068 return true; 02069 } 02070 02071 /*****************************************************************************/ 02072 /* Hessian evaluation requires 469 flops. */ 02073 /* Reductions possible when b == 1, c == 1, or d == 1 */ 02074 /*****************************************************************************/ 02075 inline int h_fcn_3i( double& obj, 02076 Vector3D g_obj[4], 02077 Matrix3D h_obj[10], 02078 const Vector3D x[4], 02079 const double a, 02080 const Exponent& b, 02081 const Exponent& c, 02082 const Vector3D& d ) 02083 { 02084 double matr[9], f; 02085 double adj_m[9], g; 02086 double dg[9], loc0, loc1, loc2, loc3, loc4; 02087 double A[3], J_A[6], J_B[9], J_C[9], cross; 02088 02089 const double scale[6] = { d[0] * d[0], d[0] * d[1], d[0] * d[2], d[1] * d[1], d[1] * d[2], d[2] * d[2] }; 02090 02091 /* Calculate M = A*inv(W). */ 02092 matr[0] = d[0] * ( x[1][0] - x[0][0] ); 02093 matr[1] = d[1] * ( x[2][0] - x[0][0] ); 02094 matr[2] = d[2] * ( x[3][0] - x[0][0] ); 02095 02096 matr[3] = d[0] * ( x[1][1] - x[0][1] ); 02097 matr[4] = d[1] * ( x[2][1] - x[0][1] ); 02098 matr[5] = d[2] * ( x[3][1] - x[0][1] ); 02099 02100 matr[6] = d[0] * ( x[1][2] - x[0][2] ); 02101 matr[7] = d[1] * ( x[2][2] - x[0][2] ); 02102 matr[8] = d[2] * ( x[3][2] - x[0][2] ); 02103 02104 /* Calculate det(M). */ 02105 dg[0] = matr[4] * matr[8] - matr[5] * matr[7]; 02106 dg[1] = matr[5] * matr[6] - matr[3] * matr[8]; 02107 dg[2] = matr[3] * matr[7] - matr[4] * matr[6]; 02108 g = matr[0] * dg[0] + matr[1] * dg[1] + matr[2] * dg[2]; 02109 if( g < MSQ_MIN ) 02110 { 02111 obj = g; 02112 return false; 02113 } 02114 02115 /* Calculate norm(M). */ 02116 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 02117 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 02118 02119 loc3 = f; 02120 loc4 = g; 02121 02122 /* Calculate objective function. */ 02123 obj = a * b.raise( f ) * c.raise( g ); 02124 02125 /* Calculate the derivative of the objective function. */ 02126 f = b.value() * obj / f; /* Constant on nabla f */ 02127 g = c.value() * obj / g; /* Constant on nable g */ 02128 f *= 2.0; /* Modification for nabla f */ 02129 02130 dg[3] = matr[2] * matr[7] - matr[1] * matr[8]; 02131 dg[4] = matr[0] * matr[8] - matr[2] * matr[6]; 02132 dg[5] = matr[1] * matr[6] - matr[0] * matr[7]; 02133 dg[6] = matr[1] * matr[5] - matr[2] * matr[4]; 02134 dg[7] = matr[2] * matr[3] - matr[0] * matr[5]; 02135 dg[8] = matr[0] * matr[4] - matr[1] * matr[3]; 02136 02137 adj_m[0] = d[0] * ( matr[0] * f + dg[0] * g ); 02138 adj_m[1] = d[1] * ( matr[1] * f + dg[1] * g ); 02139 adj_m[2] = d[2] * ( matr[2] * f + dg[2] * g ); 02140 adj_m[3] = d[0] * ( matr[3] * f + dg[3] * g ); 02141 adj_m[4] = d[1] * ( matr[4] * f + dg[4] * g ); 02142 adj_m[5] = d[2] * ( matr[5] * f + dg[5] * g ); 02143 adj_m[6] = d[0] * ( matr[6] * f + dg[6] * g ); 02144 adj_m[7] = d[1] * ( matr[7] * f + dg[7] * g ); 02145 adj_m[8] = d[2] * ( matr[8] * f + dg[8] * g ); 02146 02147 g_obj[0][0] = -adj_m[0] - adj_m[1] - adj_m[2]; 02148 g_obj[1][0] = adj_m[0]; 02149 g_obj[2][0] = adj_m[1]; 02150 g_obj[3][0] = adj_m[2]; 02151 02152 g_obj[0][1] = -adj_m[3] - adj_m[4] - adj_m[5]; 02153 g_obj[1][1] = adj_m[3]; 02154 g_obj[2][1] = adj_m[4]; 02155 g_obj[3][1] = adj_m[5]; 02156 02157 g_obj[0][2] = -adj_m[6] - adj_m[7] - adj_m[8]; 02158 g_obj[1][2] = adj_m[6]; 02159 g_obj[2][2] = adj_m[7]; 02160 g_obj[3][2] = adj_m[8]; 02161 02162 /* Calculate the hessian of the objective. */ 02163 loc0 = f; /* Constant on nabla^2 f */ 02164 loc1 = g; /* Constant on nabla^2 g */ 02165 cross = f * c.value() / loc4; /* Constant on nabla g nabla f */ 02166 f = f * ( b.value() - 1 ) / loc3; /* Constant on nabla f nabla f */ 02167 g = g * ( c.value() - 1 ) / loc4; /* Constant on nabla g nabla g */ 02168 f *= 2.0; /* Modification for nabla f */ 02169 02170 /* First block of rows */ 02171 loc3 = matr[0] * f + dg[0] * cross; 02172 loc4 = dg[0] * g + matr[0] * cross; 02173 02174 J_A[0] = loc0 + loc3 * matr[0] + loc4 * dg[0]; 02175 J_A[1] = loc3 * matr[1] + loc4 * dg[1]; 02176 J_A[2] = loc3 * matr[2] + loc4 * dg[2]; 02177 J_B[0] = loc3 * matr[3] + loc4 * dg[3]; 02178 J_B[1] = loc3 * matr[4] + loc4 * dg[4]; 02179 J_B[2] = loc3 * matr[5] + loc4 * dg[5]; 02180 J_C[0] = loc3 * matr[6] + loc4 * dg[6]; 02181 J_C[1] = loc3 * matr[7] + loc4 * dg[7]; 02182 J_C[2] = loc3 * matr[8] + loc4 * dg[8]; 02183 02184 loc3 = matr[1] * f + dg[1] * cross; 02185 loc4 = dg[1] * g + matr[1] * cross; 02186 02187 J_A[3] = loc0 + loc3 * matr[1] + loc4 * dg[1]; 02188 J_A[4] = loc3 * matr[2] + loc4 * dg[2]; 02189 J_B[3] = loc3 * matr[3] + loc4 * dg[3]; 02190 J_B[4] = loc3 * matr[4] + loc4 * dg[4]; 02191 J_B[5] = loc3 * matr[5] + loc4 * dg[5]; 02192 J_C[3] = loc3 * matr[6] + loc4 * dg[6]; 02193 J_C[4] = loc3 * matr[7] + loc4 * dg[7]; 02194 J_C[5] = loc3 * matr[8] + loc4 * dg[8]; 02195 02196 loc3 = matr[2] * f + dg[2] * cross; 02197 loc4 = dg[2] * g + matr[2] * cross; 02198 02199 J_A[5] = loc0 + loc3 * matr[2] + loc4 * dg[2]; 02200 J_B[6] = loc3 * matr[3] + loc4 * dg[3]; 02201 J_B[7] = loc3 * matr[4] + loc4 * dg[4]; 02202 J_B[8] = loc3 * matr[5] + loc4 * dg[5]; 02203 J_C[6] = loc3 * matr[6] + loc4 * dg[6]; 02204 J_C[7] = loc3 * matr[7] + loc4 * dg[7]; 02205 J_C[8] = loc3 * matr[8] + loc4 * dg[8]; 02206 02207 /* First diagonal block */ 02208 J_A[0] *= scale[0]; 02209 J_A[1] *= scale[1]; 02210 J_A[2] *= scale[2]; 02211 J_A[3] *= scale[3]; 02212 J_A[4] *= scale[4]; 02213 J_A[5] *= scale[5]; 02214 02215 A[0] = -J_A[0] - J_A[1] - J_A[2]; 02216 A[1] = -J_A[1] - J_A[3] - J_A[4]; 02217 A[2] = -J_A[2] - J_A[4] - J_A[5]; 02218 02219 h_obj[0][0][0] = -A[0] - A[1] - A[2]; 02220 h_obj[1][0][0] = A[0]; 02221 h_obj[2][0][0] = A[1]; 02222 h_obj[3][0][0] = A[2]; 02223 02224 h_obj[4][0][0] = J_A[0]; 02225 h_obj[5][0][0] = J_A[1]; 02226 h_obj[6][0][0] = J_A[2]; 02227 02228 h_obj[7][0][0] = J_A[3]; 02229 h_obj[8][0][0] = J_A[4]; 02230 02231 h_obj[9][0][0] = J_A[5]; 02232 02233 /* First off-diagonal block */ 02234 loc2 = matr[8] * loc1; 02235 J_B[1] += loc2; 02236 J_B[3] -= loc2; 02237 02238 loc2 = matr[7] * loc1; 02239 J_B[2] -= loc2; 02240 J_B[6] += loc2; 02241 02242 loc2 = matr[6] * loc1; 02243 J_B[5] += loc2; 02244 J_B[7] -= loc2; 02245 02246 J_B[0] *= scale[0]; 02247 J_B[1] *= scale[1]; 02248 J_B[2] *= scale[2]; 02249 J_B[3] *= scale[1]; 02250 J_B[4] *= scale[3]; 02251 J_B[5] *= scale[4]; 02252 J_B[6] *= scale[2]; 02253 J_B[7] *= scale[4]; 02254 J_B[8] *= scale[5]; 02255 02256 A[0] = -J_B[0] - J_B[3] - J_B[6]; 02257 A[1] = -J_B[1] - J_B[4] - J_B[7]; 02258 A[2] = -J_B[2] - J_B[5] - J_B[8]; 02259 02260 h_obj[0][0][1] = -A[0] - A[1] - A[2]; 02261 h_obj[1][0][1] = A[0]; 02262 h_obj[2][0][1] = A[1]; 02263 h_obj[3][0][1] = A[2]; 02264 02265 h_obj[1][1][0] = -J_B[0] - J_B[1] - J_B[2]; 02266 h_obj[4][0][1] = J_B[0]; 02267 h_obj[5][0][1] = J_B[1]; 02268 h_obj[6][0][1] = J_B[2]; 02269 02270 h_obj[2][1][0] = -J_B[3] - J_B[4] - J_B[5]; 02271 h_obj[5][1][0] = J_B[3]; 02272 h_obj[7][0][1] = J_B[4]; 02273 h_obj[8][0][1] = J_B[5]; 02274 02275 h_obj[3][1][0] = -J_B[6] - J_B[7] - J_B[8]; 02276 h_obj[6][1][0] = J_B[6]; 02277 h_obj[8][1][0] = J_B[7]; 02278 h_obj[9][0][1] = J_B[8]; 02279 02280 /* Second off-diagonal block */ 02281 loc2 = matr[5] * loc1; 02282 J_C[1] -= loc2; 02283 J_C[3] += loc2; 02284 02285 loc2 = matr[4] * loc1; 02286 J_C[2] += loc2; 02287 J_C[6] -= loc2; 02288 02289 loc2 = matr[3] * loc1; 02290 J_C[5] -= loc2; 02291 J_C[7] += loc2; 02292 02293 J_C[0] *= scale[0]; 02294 J_C[1] *= scale[1]; 02295 J_C[2] *= scale[2]; 02296 J_C[3] *= scale[1]; 02297 J_C[4] *= scale[3]; 02298 J_C[5] *= scale[4]; 02299 J_C[6] *= scale[2]; 02300 J_C[7] *= scale[4]; 02301 J_C[8] *= scale[5]; 02302 02303 A[0] = -J_C[0] - J_C[3] - J_C[6]; 02304 A[1] = -J_C[1] - J_C[4] - J_C[7]; 02305 A[2] = -J_C[2] - J_C[5] - J_C[8]; 02306 02307 h_obj[0][0][2] = -A[0] - A[1] - A[2]; 02308 h_obj[1][0][2] = A[0]; 02309 h_obj[2][0][2] = A[1]; 02310 h_obj[3][0][2] = A[2]; 02311 02312 h_obj[1][2][0] = -J_C[0] - J_C[1] - J_C[2]; 02313 h_obj[4][0][2] = J_C[0]; 02314 h_obj[5][0][2] = J_C[1]; 02315 h_obj[6][0][2] = J_C[2]; 02316 02317 h_obj[2][2][0] = -J_C[3] - J_C[4] - J_C[5]; 02318 h_obj[5][2][0] = J_C[3]; 02319 h_obj[7][0][2] = J_C[4]; 02320 h_obj[8][0][2] = J_C[5]; 02321 02322 h_obj[3][2][0] = -J_C[6] - J_C[7] - J_C[8]; 02323 h_obj[6][2][0] = J_C[6]; 02324 h_obj[8][2][0] = J_C[7]; 02325 h_obj[9][0][2] = J_C[8]; 02326 02327 /* Second block of rows */ 02328 loc3 = matr[3] * f + dg[3] * cross; 02329 loc4 = dg[3] * g + matr[3] * cross; 02330 02331 J_A[0] = loc0 + loc3 * matr[3] + loc4 * dg[3]; 02332 J_A[1] = loc3 * matr[4] + loc4 * dg[4]; 02333 J_A[2] = loc3 * matr[5] + loc4 * dg[5]; 02334 J_B[0] = loc3 * matr[6] + loc4 * dg[6]; 02335 J_B[1] = loc3 * matr[7] + loc4 * dg[7]; 02336 J_B[2] = loc3 * matr[8] + loc4 * dg[8]; 02337 02338 loc3 = matr[4] * f + dg[4] * cross; 02339 loc4 = dg[4] * g + matr[4] * cross; 02340 02341 J_A[3] = loc0 + loc3 * matr[4] + loc4 * dg[4]; 02342 J_A[4] = loc3 * matr[5] + loc4 * dg[5]; 02343 J_B[3] = loc3 * matr[6] + loc4 * dg[6]; 02344 J_B[4] = loc3 * matr[7] + loc4 * dg[7]; 02345 J_B[5] = loc3 * matr[8] + loc4 * dg[8]; 02346 02347 loc3 = matr[5] * f + dg[5] * cross; 02348 loc4 = dg[5] * g + matr[5] * cross; 02349 02350 J_A[5] = loc0 + loc3 * matr[5] + loc4 * dg[5]; 02351 J_B[6] = loc3 * matr[6] + loc4 * dg[6]; 02352 J_B[7] = loc3 * matr[7] + loc4 * dg[7]; 02353 J_B[8] = loc3 * matr[8] + loc4 * dg[8]; 02354 02355 /* Second diagonal block */ 02356 J_A[0] *= scale[0]; 02357 J_A[1] *= scale[1]; 02358 J_A[2] *= scale[2]; 02359 J_A[3] *= scale[3]; 02360 J_A[4] *= scale[4]; 02361 J_A[5] *= scale[5]; 02362 02363 A[0] = -J_A[0] - J_A[1] - J_A[2]; 02364 A[1] = -J_A[1] - J_A[3] - J_A[4]; 02365 A[2] = -J_A[2] - J_A[4] - J_A[5]; 02366 02367 h_obj[0][1][1] = -A[0] - A[1] - A[2]; 02368 h_obj[1][1][1] = A[0]; 02369 h_obj[2][1][1] = A[1]; 02370 h_obj[3][1][1] = A[2]; 02371 02372 h_obj[4][1][1] = J_A[0]; 02373 h_obj[5][1][1] = J_A[1]; 02374 h_obj[6][1][1] = J_A[2]; 02375 02376 h_obj[7][1][1] = J_A[3]; 02377 h_obj[8][1][1] = J_A[4]; 02378 02379 h_obj[9][1][1] = J_A[5]; 02380 02381 /* Third off-diagonal block */ 02382 loc2 = matr[2] * loc1; 02383 J_B[1] += loc2; 02384 J_B[3] -= loc2; 02385 02386 loc2 = matr[1] * loc1; 02387 J_B[2] -= loc2; 02388 J_B[6] += loc2; 02389 02390 loc2 = matr[0] * loc1; 02391 J_B[5] += loc2; 02392 J_B[7] -= loc2; 02393 02394 J_B[0] *= scale[0]; 02395 J_B[1] *= scale[1]; 02396 J_B[2] *= scale[2]; 02397 J_B[3] *= scale[1]; 02398 J_B[4] *= scale[3]; 02399 J_B[5] *= scale[4]; 02400 J_B[6] *= scale[2]; 02401 J_B[7] *= scale[4]; 02402 J_B[8] *= scale[5]; 02403 02404 A[0] = -J_B[0] - J_B[3] - J_B[6]; 02405 A[1] = -J_B[1] - J_B[4] - J_B[7]; 02406 A[2] = -J_B[2] - J_B[5] - J_B[8]; 02407 02408 h_obj[0][1][2] = -A[0] - A[1] - A[2]; 02409 h_obj[1][1][2] = A[0]; 02410 h_obj[2][1][2] = A[1]; 02411 h_obj[3][1][2] = A[2]; 02412 02413 h_obj[1][2][1] = -J_B[0] - J_B[1] - J_B[2]; 02414 h_obj[4][1][2] = J_B[0]; 02415 h_obj[5][1][2] = J_B[1]; 02416 h_obj[6][1][2] = J_B[2]; 02417 02418 h_obj[2][2][1] = -J_B[3] - J_B[4] - J_B[5]; 02419 h_obj[5][2][1] = J_B[3]; 02420 h_obj[7][1][2] = J_B[4]; 02421 h_obj[8][1][2] = J_B[5]; 02422 02423 h_obj[3][2][1] = -J_B[6] - J_B[7] - J_B[8]; 02424 h_obj[6][2][1] = J_B[6]; 02425 h_obj[8][2][1] = J_B[7]; 02426 h_obj[9][1][2] = J_B[8]; 02427 02428 /* Third block of rows */ 02429 loc3 = matr[6] * f + dg[6] * cross; 02430 loc4 = dg[6] * g + matr[6] * cross; 02431 02432 J_A[0] = loc0 + loc3 * matr[6] + loc4 * dg[6]; 02433 J_A[1] = loc3 * matr[7] + loc4 * dg[7]; 02434 J_A[2] = loc3 * matr[8] + loc4 * dg[8]; 02435 02436 loc3 = matr[7] * f + dg[7] * cross; 02437 loc4 = dg[7] * g + matr[7] * cross; 02438 02439 J_A[3] = loc0 + loc3 * matr[7] + loc4 * dg[7]; 02440 J_A[4] = loc3 * matr[8] + loc4 * dg[8]; 02441 02442 loc3 = matr[8] * f + dg[8] * cross; 02443 loc4 = dg[8] * g + matr[8] * cross; 02444 02445 J_A[5] = loc0 + loc3 * matr[8] + loc4 * dg[8]; 02446 02447 /* Third diagonal block */ 02448 J_A[0] *= scale[0]; 02449 J_A[1] *= scale[1]; 02450 J_A[2] *= scale[2]; 02451 J_A[3] *= scale[3]; 02452 J_A[4] *= scale[4]; 02453 J_A[5] *= scale[5]; 02454 02455 A[0] = -J_A[0] - J_A[1] - J_A[2]; 02456 A[1] = -J_A[1] - J_A[3] - J_A[4]; 02457 A[2] = -J_A[2] - J_A[4] - J_A[5]; 02458 02459 h_obj[0][2][2] = -A[0] - A[1] - A[2]; 02460 h_obj[1][2][2] = A[0]; 02461 h_obj[2][2][2] = A[1]; 02462 h_obj[3][2][2] = A[2]; 02463 02464 h_obj[4][2][2] = J_A[0]; 02465 h_obj[5][2][2] = J_A[1]; 02466 h_obj[6][2][2] = J_A[2]; 02467 02468 h_obj[7][2][2] = J_A[3]; 02469 h_obj[8][2][2] = J_A[4]; 02470 02471 h_obj[9][2][2] = J_A[5]; 02472 02473 // completes diagonal blocks. 02474 h_obj[0].fill_lower_triangle(); 02475 h_obj[4].fill_lower_triangle(); 02476 h_obj[7].fill_lower_triangle(); 02477 h_obj[9].fill_lower_triangle(); 02478 return true; 02479 } 02480 02481 /********************************************************************* 02482 * Reference tetrahedral elements to halves of an ideal pyramid. 02483 * Vertices should be ordered such that the edge between the 2nd and 02484 * 3rd vertices is the one longer edge in the reference tetrahedron 02485 * (the diagonal of the base of the pyramid of which the tetrahedron 02486 * is one half of). 02487 * 1 0 1/2 1 0 -1/sqrt(2) 02488 * W = 0 1 1/2 inv(W) = 0 1 -1/sqrt(2) 02489 * 0 0 1/sqrt(2) 0 0 sqrt(2) 02490 * 02491 *********************************************************************/ 02492 inline bool m_fcn_3p( double& obj, const Vector3D x[4], const double a, const Exponent& b, const Exponent& c ) 02493 { 02494 const double h = 0.5; /* h = 1 / (2*height) */ 02495 02496 double matr[9], f; 02497 double g; 02498 02499 /* Calculate M = A*inv(W). */ 02500 matr[0] = x[1][0] - x[0][0]; 02501 matr[1] = x[2][0] - x[0][0]; 02502 matr[2] = ( 2.0 * x[3][0] - x[1][0] - x[2][0] ) * h; 02503 02504 matr[3] = x[1][1] - x[0][1]; 02505 matr[4] = x[2][1] - x[0][1]; 02506 matr[5] = ( 2.0 * x[3][1] - x[1][1] - x[2][1] ) * h; 02507 02508 matr[6] = x[1][2] - x[0][2]; 02509 matr[7] = x[2][2] - x[0][2]; 02510 matr[8] = ( 2.0 * x[3][2] - x[1][2] - x[2][2] ) * h; 02511 02512 /* Calculate det(M). */ 02513 g = matr[0] * ( matr[4] * matr[8] - matr[5] * matr[7] ) + matr[1] * ( matr[5] * matr[6] - matr[3] * matr[8] ) + 02514 matr[2] * ( matr[3] * matr[7] - matr[4] * matr[6] ); 02515 if( g < MSQ_MIN ) 02516 { 02517 obj = g; 02518 return false; 02519 } 02520 02521 /* Calculate norm(M). */ 02522 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 02523 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 02524 02525 /* Calculate objective function. */ 02526 obj = a * b.raise( f ) * c.raise( g ); 02527 return true; 02528 } 02529 02530 inline bool g_fcn_3p( double& obj, 02531 Vector3D g_obj[4], 02532 const Vector3D x[4], 02533 const double a, 02534 const Exponent& b, 02535 const Exponent& c ) 02536 { 02537 const double h = 0.5; /* h = 1 / (2*height) */ 02538 const double th = 1.0; /* h = 1 / (height) */ 02539 02540 double matr[9], f; 02541 double adj_m[9], g; 02542 double loc1, loc2, loc3; 02543 02544 /* Calculate M = A*inv(W). */ 02545 matr[0] = x[1][0] - x[0][0]; 02546 matr[1] = x[2][0] - x[0][0]; 02547 matr[2] = ( 2.0 * x[3][0] - x[1][0] - x[2][0] ) * h; 02548 02549 matr[3] = x[1][1] - x[0][1]; 02550 matr[4] = x[2][1] - x[0][1]; 02551 matr[5] = ( 2.0 * x[3][1] - x[1][1] - x[2][1] ) * h; 02552 02553 matr[6] = x[1][2] - x[0][2]; 02554 matr[7] = x[2][2] - x[0][2]; 02555 matr[8] = ( 2.0 * x[3][2] - x[1][2] - x[2][2] ) * h; 02556 02557 /* Calculate det(M). */ 02558 loc1 = matr[4] * matr[8] - matr[5] * matr[7]; 02559 loc2 = matr[5] * matr[6] - matr[3] * matr[8]; 02560 loc3 = matr[3] * matr[7] - matr[4] * matr[6]; 02561 g = matr[0] * loc1 + matr[1] * loc2 + matr[2] * loc3; 02562 if( g < MSQ_MIN ) 02563 { 02564 obj = g; 02565 return false; 02566 } 02567 02568 /* Calculate norm(M). */ 02569 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 02570 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 02571 02572 /* Calculate objective function. */ 02573 obj = a * b.raise( f ) * c.raise( g ); 02574 02575 /* Calculate the derivative of the objective function. */ 02576 f = b.value() * obj / f; /* Constant on nabla f */ 02577 g = c.value() * obj / g; /* Constant on nable g */ 02578 f *= 2.0; /* Modification for nabla f */ 02579 02580 adj_m[0] = matr[0] * f + loc1 * g; 02581 adj_m[1] = matr[1] * f + loc2 * g; 02582 adj_m[2] = matr[2] * f + loc3 * g; 02583 02584 loc1 = matr[0] * g; 02585 loc2 = matr[1] * g; 02586 loc3 = matr[2] * g; 02587 02588 adj_m[3] = matr[3] * f + loc3 * matr[7] - loc2 * matr[8]; 02589 adj_m[4] = matr[4] * f + loc1 * matr[8] - loc3 * matr[6]; 02590 adj_m[5] = matr[5] * f + loc2 * matr[6] - loc1 * matr[7]; 02591 02592 adj_m[6] = matr[6] * f + loc2 * matr[5] - loc3 * matr[4]; 02593 adj_m[7] = matr[7] * f + loc3 * matr[3] - loc1 * matr[5]; 02594 adj_m[8] = matr[8] * f + loc1 * matr[4] - loc2 * matr[3]; 02595 02596 g_obj[0][0] = -adj_m[0] - adj_m[1]; 02597 g_obj[1][0] = adj_m[0] - h * adj_m[2]; 02598 g_obj[2][0] = adj_m[1] - h * adj_m[2]; 02599 g_obj[3][0] = th * adj_m[2]; 02600 02601 g_obj[0][1] = -adj_m[3] - adj_m[4]; 02602 g_obj[1][1] = adj_m[3] - h * adj_m[5]; 02603 g_obj[2][1] = adj_m[4] - h * adj_m[5]; 02604 g_obj[3][1] = th * adj_m[5]; 02605 02606 g_obj[0][2] = -adj_m[6] - adj_m[7]; 02607 g_obj[1][2] = adj_m[6] - h * adj_m[8]; 02608 g_obj[2][2] = adj_m[7] - h * adj_m[8]; 02609 g_obj[3][2] = th * adj_m[8]; 02610 return true; 02611 } 02612 02613 inline bool h_fcn_3p( double& obj, 02614 Vector3D g_obj[4], 02615 Matrix3D h_obj[10], 02616 const Vector3D x[4], 02617 const double a, 02618 const Exponent& b, 02619 const Exponent& c ) 02620 { 02621 const double h = 0.5; /* h = 1 / (2*height) */ 02622 const double th = 1.0; /* h = 1 / (height) */ 02623 02624 double matr[9], f; 02625 double adj_m[9], g; 02626 double dg[9], loc0, loc1, loc2, loc3, loc4; 02627 double A[12], J_A[6], J_B[9], J_C[9], cross; 02628 02629 /* Calculate M = A*inv(W). */ 02630 matr[0] = x[1][0] - x[0][0]; 02631 matr[1] = x[2][0] - x[0][0]; 02632 matr[2] = ( 2.0 * x[3][0] - x[1][0] - x[2][0] ) * h; 02633 02634 matr[3] = x[1][1] - x[0][1]; 02635 matr[4] = x[2][1] - x[0][1]; 02636 matr[5] = ( 2.0 * x[3][1] - x[1][1] - x[2][1] ) * h; 02637 02638 matr[6] = x[1][2] - x[0][2]; 02639 matr[7] = x[2][2] - x[0][2]; 02640 matr[8] = ( 2.0 * x[3][2] - x[1][2] - x[2][2] ) * h; 02641 02642 /* Calculate det(M). */ 02643 dg[0] = matr[4] * matr[8] - matr[5] * matr[7]; 02644 dg[1] = matr[5] * matr[6] - matr[3] * matr[8]; 02645 dg[2] = matr[3] * matr[7] - matr[4] * matr[6]; 02646 g = matr[0] * dg[0] + matr[1] * dg[1] + matr[2] * dg[2]; 02647 if( g < MSQ_MIN ) 02648 { 02649 obj = g; 02650 return false; 02651 } 02652 02653 dg[3] = matr[2] * matr[7] - matr[1] * matr[8]; 02654 dg[4] = matr[0] * matr[8] - matr[2] * matr[6]; 02655 dg[5] = matr[1] * matr[6] - matr[0] * matr[7]; 02656 dg[6] = matr[1] * matr[5] - matr[2] * matr[4]; 02657 dg[7] = matr[2] * matr[3] - matr[0] * matr[5]; 02658 dg[8] = matr[0] * matr[4] - matr[1] * matr[3]; 02659 02660 /* Calculate norm(M). */ 02661 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 02662 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 02663 02664 loc3 = f; 02665 loc4 = g; 02666 02667 /* Calculate objective function. */ 02668 obj = a * b.raise( f ) * c.raise( g ); 02669 02670 /* Calculate the derivative of the objective function. */ 02671 f = b.value() * obj / f; /* Constant on nabla f */ 02672 g = c.value() * obj / g; /* Constant on nable g */ 02673 f *= 2.0; /* Modification for nabla f */ 02674 02675 adj_m[0] = matr[0] * f + dg[0] * g; 02676 adj_m[1] = matr[1] * f + dg[1] * g; 02677 adj_m[2] = matr[2] * f + dg[2] * g; 02678 adj_m[3] = matr[3] * f + dg[3] * g; 02679 adj_m[4] = matr[4] * f + dg[4] * g; 02680 adj_m[5] = matr[5] * f + dg[5] * g; 02681 adj_m[6] = matr[6] * f + dg[6] * g; 02682 adj_m[7] = matr[7] * f + dg[7] * g; 02683 adj_m[8] = matr[8] * f + dg[8] * g; 02684 02685 g_obj[0][0] = -adj_m[0] - adj_m[1]; 02686 g_obj[1][0] = adj_m[0] - h * adj_m[2]; 02687 g_obj[2][0] = adj_m[1] - h * adj_m[2]; 02688 g_obj[3][0] = th * adj_m[2]; 02689 02690 g_obj[0][1] = -adj_m[3] - adj_m[4]; 02691 g_obj[1][1] = adj_m[3] - h * adj_m[5]; 02692 g_obj[2][1] = adj_m[4] - h * adj_m[5]; 02693 g_obj[3][1] = th * adj_m[5]; 02694 02695 g_obj[0][2] = -adj_m[6] - adj_m[7]; 02696 g_obj[1][2] = adj_m[6] - h * adj_m[8]; 02697 g_obj[2][2] = adj_m[7] - h * adj_m[8]; 02698 g_obj[3][2] = th * adj_m[8]; 02699 02700 /* Calculate the hessian of the objective. */ 02701 loc0 = f; /* Constant on nabla^2 f */ 02702 loc1 = g; /* Constant on nabla^2 g */ 02703 cross = f * c.value() / loc4; /* Constant on nabla g nabla f */ 02704 f = f * ( b.value() - 1 ) / loc3; /* Constant on nabla f nabla f */ 02705 g = g * ( c.value() - 1 ) / loc4; /* Constant on nabla g nabla g */ 02706 f *= 2.0; /* Modification for nabla f */ 02707 02708 /* First block of rows */ 02709 loc3 = matr[0] * f + dg[0] * cross; 02710 loc4 = dg[0] * g + matr[0] * cross; 02711 02712 J_A[0] = loc0 + loc3 * matr[0] + loc4 * dg[0]; 02713 J_A[1] = loc3 * matr[1] + loc4 * dg[1]; 02714 J_A[2] = loc3 * matr[2] + loc4 * dg[2]; 02715 J_B[0] = loc3 * matr[3] + loc4 * dg[3]; 02716 J_B[1] = loc3 * matr[4] + loc4 * dg[4]; 02717 J_B[2] = loc3 * matr[5] + loc4 * dg[5]; 02718 J_C[0] = loc3 * matr[6] + loc4 * dg[6]; 02719 J_C[1] = loc3 * matr[7] + loc4 * dg[7]; 02720 J_C[2] = loc3 * matr[8] + loc4 * dg[8]; 02721 02722 loc3 = matr[1] * f + dg[1] * cross; 02723 loc4 = dg[1] * g + matr[1] * cross; 02724 02725 J_A[3] = loc0 + loc3 * matr[1] + loc4 * dg[1]; 02726 J_A[4] = loc3 * matr[2] + loc4 * dg[2]; 02727 J_B[3] = loc3 * matr[3] + loc4 * dg[3]; 02728 J_B[4] = loc3 * matr[4] + loc4 * dg[4]; 02729 J_B[5] = loc3 * matr[5] + loc4 * dg[5]; 02730 J_C[3] = loc3 * matr[6] + loc4 * dg[6]; 02731 J_C[4] = loc3 * matr[7] + loc4 * dg[7]; 02732 J_C[5] = loc3 * matr[8] + loc4 * dg[8]; 02733 02734 loc3 = matr[2] * f + dg[2] * cross; 02735 loc4 = dg[2] * g + matr[2] * cross; 02736 02737 J_A[5] = loc0 + loc3 * matr[2] + loc4 * dg[2]; 02738 J_B[6] = loc3 * matr[3] + loc4 * dg[3]; 02739 J_B[7] = loc3 * matr[4] + loc4 * dg[4]; 02740 J_B[8] = loc3 * matr[5] + loc4 * dg[5]; 02741 J_C[6] = loc3 * matr[6] + loc4 * dg[6]; 02742 J_C[7] = loc3 * matr[7] + loc4 * dg[7]; 02743 J_C[8] = loc3 * matr[8] + loc4 * dg[8]; 02744 02745 /* First diagonal block */ 02746 A[0] = -J_A[0] - J_A[1]; 02747 A[1] = J_A[0] - h * J_A[2]; 02748 A[2] = J_A[1] - h * J_A[2]; 02749 A[3] = th * J_A[2]; 02750 02751 A[4] = -J_A[1] - J_A[3]; 02752 A[5] = J_A[1] - h * J_A[4]; 02753 A[6] = J_A[3] - h * J_A[4]; 02754 A[7] = th * J_A[4]; 02755 02756 A[8] = -J_A[2] - J_A[4]; 02757 A[9] = J_A[2] - h * J_A[5]; 02758 A[10] = J_A[4] - h * J_A[5]; 02759 A[11] = th * J_A[5]; 02760 02761 h_obj[0][0][0] = -A[0] - A[4]; 02762 h_obj[1][0][0] = A[0] - h * A[8]; 02763 h_obj[2][0][0] = A[4] - h * A[8]; 02764 h_obj[3][0][0] = th * A[8]; 02765 02766 h_obj[4][0][0] = A[1] - h * A[9]; 02767 h_obj[5][0][0] = A[5] - h * A[9]; 02768 h_obj[6][0][0] = th * A[9]; 02769 02770 h_obj[7][0][0] = A[6] - h * A[10]; 02771 h_obj[8][0][0] = th * A[10]; 02772 02773 h_obj[9][0][0] = th * A[11]; 02774 02775 /* First off-diagonal block */ 02776 loc2 = matr[8] * loc1; 02777 J_B[1] += loc2; 02778 J_B[3] -= loc2; 02779 02780 loc2 = matr[7] * loc1; 02781 J_B[2] -= loc2; 02782 J_B[6] += loc2; 02783 02784 loc2 = matr[6] * loc1; 02785 J_B[5] += loc2; 02786 J_B[7] -= loc2; 02787 02788 A[0] = -J_B[0] - J_B[1]; 02789 A[1] = J_B[0] - h * J_B[2]; 02790 A[2] = J_B[1] - h * J_B[2]; 02791 A[3] = th * J_B[2]; 02792 02793 A[4] = -J_B[3] - J_B[4]; 02794 A[5] = J_B[3] - h * J_B[5]; 02795 A[6] = J_B[4] - h * J_B[5]; 02796 A[7] = th * J_B[5]; 02797 02798 A[8] = -J_B[6] - J_B[7]; 02799 A[9] = J_B[6] - h * J_B[8]; 02800 A[10] = J_B[7] - h * J_B[8]; 02801 A[11] = th * J_B[8]; 02802 02803 h_obj[0][0][1] = -A[0] - A[4]; 02804 h_obj[1][1][0] = A[0] - h * A[8]; 02805 h_obj[2][1][0] = A[4] - h * A[8]; 02806 h_obj[3][1][0] = th * A[8]; 02807 02808 h_obj[1][0][1] = -A[1] - A[5]; 02809 h_obj[4][0][1] = A[1] - h * A[9]; 02810 h_obj[5][1][0] = A[5] - h * A[9]; 02811 h_obj[6][1][0] = th * A[9]; 02812 02813 h_obj[2][0][1] = -A[2] - A[6]; 02814 h_obj[5][0][1] = A[2] - h * A[10]; 02815 h_obj[7][0][1] = A[6] - h * A[10]; 02816 h_obj[8][1][0] = th * A[10]; 02817 02818 h_obj[3][0][1] = -A[3] - A[7]; 02819 h_obj[6][0][1] = A[3] - h * A[11]; 02820 h_obj[8][0][1] = A[7] - h * A[11]; 02821 h_obj[9][0][1] = th * A[11]; 02822 02823 /* Second off-diagonal block */ 02824 loc2 = matr[5] * loc1; 02825 J_C[1] -= loc2; 02826 J_C[3] += loc2; 02827 02828 loc2 = matr[4] * loc1; 02829 J_C[2] += loc2; 02830 J_C[6] -= loc2; 02831 02832 loc2 = matr[3] * loc1; 02833 J_C[5] -= loc2; 02834 J_C[7] += loc2; 02835 02836 A[0] = -J_C[0] - J_C[1]; 02837 A[1] = J_C[0] - h * J_C[2]; 02838 A[2] = J_C[1] - h * J_C[2]; 02839 A[3] = th * J_C[2]; 02840 02841 A[4] = -J_C[3] - J_C[4]; 02842 A[5] = J_C[3] - h * J_C[5]; 02843 A[6] = J_C[4] - h * J_C[5]; 02844 A[7] = th * J_C[5]; 02845 02846 A[8] = -J_C[6] - J_C[7]; 02847 A[9] = J_C[6] - h * J_C[8]; 02848 A[10] = J_C[7] - h * J_C[8]; 02849 A[11] = th * J_C[8]; 02850 02851 h_obj[0][0][2] = -A[0] - A[4]; 02852 h_obj[1][2][0] = A[0] - h * A[8]; 02853 h_obj[2][2][0] = A[4] - h * A[8]; 02854 h_obj[3][2][0] = th * A[8]; 02855 02856 h_obj[1][0][2] = -A[1] - A[5]; 02857 h_obj[4][0][2] = A[1] - h * A[9]; 02858 h_obj[5][2][0] = A[5] - h * A[9]; 02859 h_obj[6][2][0] = th * A[9]; 02860 02861 h_obj[2][0][2] = -A[2] - A[6]; 02862 h_obj[5][0][2] = A[2] - h * A[10]; 02863 h_obj[7][0][2] = A[6] - h * A[10]; 02864 h_obj[8][2][0] = th * A[10]; 02865 02866 h_obj[3][0][2] = -A[3] - A[7]; 02867 h_obj[6][0][2] = A[3] - h * A[11]; 02868 h_obj[8][0][2] = A[7] - h * A[11]; 02869 h_obj[9][0][2] = th * A[11]; 02870 02871 /* Second block of rows */ 02872 loc3 = matr[3] * f + dg[3] * cross; 02873 loc4 = dg[3] * g + matr[3] * cross; 02874 02875 J_A[0] = loc0 + loc3 * matr[3] + loc4 * dg[3]; 02876 J_A[1] = loc3 * matr[4] + loc4 * dg[4]; 02877 J_A[2] = loc3 * matr[5] + loc4 * dg[5]; 02878 J_B[0] = loc3 * matr[6] + loc4 * dg[6]; 02879 J_B[1] = loc3 * matr[7] + loc4 * dg[7]; 02880 J_B[2] = loc3 * matr[8] + loc4 * dg[8]; 02881 02882 loc3 = matr[4] * f + dg[4] * cross; 02883 loc4 = dg[4] * g + matr[4] * cross; 02884 02885 J_A[3] = loc0 + loc3 * matr[4] + loc4 * dg[4]; 02886 J_A[4] = loc3 * matr[5] + loc4 * dg[5]; 02887 J_B[3] = loc3 * matr[6] + loc4 * dg[6]; 02888 J_B[4] = loc3 * matr[7] + loc4 * dg[7]; 02889 J_B[5] = loc3 * matr[8] + loc4 * dg[8]; 02890 02891 loc3 = matr[5] * f + dg[5] * cross; 02892 loc4 = dg[5] * g + matr[5] * cross; 02893 02894 J_A[5] = loc0 + loc3 * matr[5] + loc4 * dg[5]; 02895 J_B[6] = loc3 * matr[6] + loc4 * dg[6]; 02896 J_B[7] = loc3 * matr[7] + loc4 * dg[7]; 02897 J_B[8] = loc3 * matr[8] + loc4 * dg[8]; 02898 02899 /* Second diagonal block */ 02900 A[0] = -J_A[0] - J_A[1]; 02901 A[1] = J_A[0] - h * J_A[2]; 02902 A[2] = J_A[1] - h * J_A[2]; 02903 A[3] = th * J_A[2]; 02904 02905 A[4] = -J_A[1] - J_A[3]; 02906 A[5] = J_A[1] - h * J_A[4]; 02907 A[6] = J_A[3] - h * J_A[4]; 02908 A[7] = th * J_A[4]; 02909 02910 A[8] = -J_A[2] - J_A[4]; 02911 A[9] = J_A[2] - h * J_A[5]; 02912 A[10] = J_A[4] - h * J_A[5]; 02913 A[11] = th * J_A[5]; 02914 02915 h_obj[0][1][1] = -A[0] - A[4]; 02916 h_obj[1][1][1] = A[0] - h * A[8]; 02917 h_obj[2][1][1] = A[4] - h * A[8]; 02918 h_obj[3][1][1] = th * A[8]; 02919 02920 h_obj[4][1][1] = A[1] - h * A[9]; 02921 h_obj[5][1][1] = A[5] - h * A[9]; 02922 h_obj[6][1][1] = th * A[9]; 02923 02924 h_obj[7][1][1] = A[6] - h * A[10]; 02925 h_obj[8][1][1] = th * A[10]; 02926 02927 h_obj[9][1][1] = th * A[11]; 02928 02929 /* Third off-diagonal block */ 02930 loc2 = matr[2] * loc1; 02931 J_B[1] += loc2; 02932 J_B[3] -= loc2; 02933 02934 loc2 = matr[1] * loc1; 02935 J_B[2] -= loc2; 02936 J_B[6] += loc2; 02937 02938 loc2 = matr[0] * loc1; 02939 J_B[5] += loc2; 02940 J_B[7] -= loc2; 02941 02942 A[0] = -J_B[0] - J_B[1]; 02943 A[1] = J_B[0] - h * J_B[2]; 02944 A[2] = J_B[1] - h * J_B[2]; 02945 A[3] = th * J_B[2]; 02946 02947 A[4] = -J_B[3] - J_B[4]; 02948 A[5] = J_B[3] - h * J_B[5]; 02949 A[6] = J_B[4] - h * J_B[5]; 02950 A[7] = th * J_B[5]; 02951 02952 A[8] = -J_B[6] - J_B[7]; 02953 A[9] = J_B[6] - h * J_B[8]; 02954 A[10] = J_B[7] - h * J_B[8]; 02955 A[11] = th * J_B[8]; 02956 02957 h_obj[0][1][2] = -A[0] - A[4]; 02958 h_obj[1][2][1] = A[0] - h * A[8]; 02959 h_obj[2][2][1] = A[4] - h * A[8]; 02960 h_obj[3][2][1] = th * A[8]; 02961 02962 h_obj[1][1][2] = -A[1] - A[5]; 02963 h_obj[4][1][2] = A[1] - h * A[9]; 02964 h_obj[5][2][1] = A[5] - h * A[9]; 02965 h_obj[6][2][1] = th * A[9]; 02966 02967 h_obj[2][1][2] = -A[2] - A[6]; 02968 h_obj[5][1][2] = A[2] - h * A[10]; 02969 h_obj[7][1][2] = A[6] - h * A[10]; 02970 h_obj[8][2][1] = th * A[10]; 02971 02972 h_obj[3][1][2] = -A[3] - A[7]; 02973 h_obj[6][1][2] = A[3] - h * A[11]; 02974 h_obj[8][1][2] = A[7] - h * A[11]; 02975 h_obj[9][1][2] = th * A[11]; 02976 02977 /* Third block of rows */ 02978 loc3 = matr[6] * f + dg[6] * cross; 02979 loc4 = dg[6] * g + matr[6] * cross; 02980 02981 J_A[0] = loc0 + loc3 * matr[6] + loc4 * dg[6]; 02982 J_A[1] = loc3 * matr[7] + loc4 * dg[7]; 02983 J_A[2] = loc3 * matr[8] + loc4 * dg[8]; 02984 02985 loc3 = matr[7] * f + dg[7] * cross; 02986 loc4 = dg[7] * g + matr[7] * cross; 02987 02988 J_A[3] = loc0 + loc3 * matr[7] + loc4 * dg[7]; 02989 J_A[4] = loc3 * matr[8] + loc4 * dg[8]; 02990 02991 loc3 = matr[8] * f + dg[8] * cross; 02992 loc4 = dg[8] * g + matr[8] * cross; 02993 02994 J_A[5] = loc0 + loc3 * matr[8] + loc4 * dg[8]; 02995 02996 /* Third diagonal block */ 02997 A[0] = -J_A[0] - J_A[1]; 02998 A[1] = J_A[0] - h * J_A[2]; 02999 A[2] = J_A[1] - h * J_A[2]; 03000 A[3] = th * J_A[2]; 03001 03002 A[4] = -J_A[1] - J_A[3]; 03003 A[5] = J_A[1] - h * J_A[4]; 03004 A[6] = J_A[3] - h * J_A[4]; 03005 A[7] = th * J_A[4]; 03006 03007 A[8] = -J_A[2] - J_A[4]; 03008 A[9] = J_A[2] - h * J_A[5]; 03009 A[10] = J_A[4] - h * J_A[5]; 03010 A[11] = th * J_A[5]; 03011 03012 h_obj[0][2][2] = -A[0] - A[4]; 03013 h_obj[1][2][2] = A[0] - h * A[8]; 03014 h_obj[2][2][2] = A[4] - h * A[8]; 03015 h_obj[3][2][2] = th * A[8]; 03016 03017 h_obj[4][2][2] = A[1] - h * A[9]; 03018 h_obj[5][2][2] = A[5] - h * A[9]; 03019 h_obj[6][2][2] = th * A[9]; 03020 03021 h_obj[7][2][2] = A[6] - h * A[10]; 03022 h_obj[8][2][2] = th * A[10]; 03023 03024 h_obj[9][2][2] = th * A[11]; 03025 03026 #if 0 03027 int i, j, k, l; 03028 double nobj; 03029 Vector3D nx[4]; 03030 Vector3D ng_obj[4]; 03031 03032 for (i = 0; i < 4; ++i) { 03033 nx[i] = x[i]; 03034 ng_obj[i] = 0.0; 03035 } 03036 03037 m_fcn_3p(obj, x, a, b, c); 03038 for (i = 0; i < 4; ++i) { 03039 for (j = 0; j < 3; ++j) { 03040 nx[i][j] += 1e-6; 03041 m_fcn_3p(nobj, nx, a, b, c); 03042 nx[i][j] = x[i][j]; 03043 03044 ng_obj[i][j] = (nobj - obj) / 1e-6; 03045 std::cout << i << " " << j << " " << g_obj[i][j] << " " << ng_obj[i][j] << std::endl; 03046 } 03047 } 03048 std::cout << std::endl; 03049 03050 for (i = 0; i < 4; ++i) { 03051 for (j = 0; j < 3; ++j) { 03052 nx[i][j] += 1e-6; 03053 g_fcn_3p(nobj, ng_obj, nx, a, b, c); 03054 nx[i][j] = x[i][j]; 03055 03056 printf("%d %d", i, j); 03057 for (k = 0; k < 4; ++k) { 03058 for (l = 0; l < 3; ++l) { 03059 printf(" % 5.4e", (ng_obj[k][l] - g_obj[k][l]) / 1e-6); 03060 } 03061 } 03062 printf("\n"); 03063 } 03064 } 03065 03066 for (i = 0; i < 10; ++i) { 03067 std::cout << i << std::endl << h_obj[i] << std::endl << std::endl; 03068 } 03069 #endif 03070 03071 // completes diagonal blocks. 03072 h_obj[0].fill_lower_triangle(); 03073 h_obj[4].fill_lower_triangle(); 03074 h_obj[7].fill_lower_triangle(); 03075 h_obj[9].fill_lower_triangle(); 03076 return true; 03077 } 03078 03079 /********************************************************************* 03080 * Reference tetrahedral elements to corners of an ideal wedge element. 03081 * Vertices should be ordered such that the first three vertices form 03082 * the ideally-equaliteral face of the tetrahedron (the end of the 03083 * wedge) and the first and fourth vertices form the tetrahedral edge 03084 * orthogonal to the ideally-equaliteral face (the lateral edge of the 03085 * edge.) 03086 * 1 1/2 0 1 -1/sqrt(3) 0 03087 * W = 0 sqrt(3)/2 0 inv(W) = 0 2/sqrt(3) 0 03088 * 0 0 1 0 0 1 03089 * 03090 *********************************************************************/ 03091 inline bool m_fcn_3w( double& obj, const Vector3D x[4], const double a, const Exponent& b, const Exponent& c ) 03092 { 03093 double matr[9], f, g; 03094 double loc1, loc2, loc3; 03095 03096 /* Calculate M = A*inv(W). */ 03097 matr[0] = x[1][0] - x[0][0]; 03098 matr[1] = isqrt3 * ( 2 * x[2][0] - x[1][0] - x[0][0] ); 03099 matr[2] = x[3][0] - x[0][0]; 03100 03101 matr[3] = x[1][1] - x[0][1]; 03102 matr[4] = isqrt3 * ( 2 * x[2][1] - x[1][1] - x[0][1] ); 03103 matr[5] = x[3][1] - x[0][1]; 03104 03105 matr[6] = x[1][2] - x[0][2]; 03106 matr[7] = isqrt3 * ( 2 * x[2][2] - x[1][2] - x[0][2] ); 03107 matr[8] = x[3][2] - x[0][2]; 03108 03109 /* Calculate det(M). */ 03110 loc1 = matr[4] * matr[8] - matr[5] * matr[7]; 03111 loc2 = matr[5] * matr[6] - matr[3] * matr[8]; 03112 loc3 = matr[3] * matr[7] - matr[4] * matr[6]; 03113 g = matr[0] * loc1 + matr[1] * loc2 + matr[2] * loc3; 03114 if( g < MSQ_MIN ) 03115 { 03116 obj = g; 03117 return false; 03118 } 03119 03120 /* Calculate norm(M). */ 03121 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 03122 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 03123 03124 /* Calculate objective function. */ 03125 obj = a * b.raise( f ) * c.raise( g ); 03126 return true; 03127 } 03128 03129 inline bool g_fcn_3w( double& obj, 03130 Vector3D g_obj[4], 03131 const Vector3D x[4], 03132 const double a, 03133 const Exponent& b, 03134 const Exponent& c ) 03135 { 03136 double matr[9], f; 03137 double adj_m[9], g; 03138 double loc1, loc2, loc3; 03139 03140 /* Calculate M = A*inv(W). */ 03141 matr[0] = x[1][0] - x[0][0]; 03142 matr[1] = isqrt3 * ( 2 * x[2][0] - x[1][0] - x[0][0] ); 03143 matr[2] = x[3][0] - x[0][0]; 03144 03145 matr[3] = x[1][1] - x[0][1]; 03146 matr[4] = isqrt3 * ( 2 * x[2][1] - x[1][1] - x[0][1] ); 03147 matr[5] = x[3][1] - x[0][1]; 03148 03149 matr[6] = x[1][2] - x[0][2]; 03150 matr[7] = isqrt3 * ( 2 * x[2][2] - x[1][2] - x[0][2] ); 03151 matr[8] = x[3][2] - x[0][2]; 03152 03153 /* Calculate det(M). */ 03154 loc1 = matr[4] * matr[8] - matr[5] * matr[7]; 03155 loc2 = matr[5] * matr[6] - matr[3] * matr[8]; 03156 loc3 = matr[3] * matr[7] - matr[4] * matr[6]; 03157 g = matr[0] * loc1 + matr[1] * loc2 + matr[2] * loc3; 03158 if( g < MSQ_MIN ) 03159 { 03160 obj = g; 03161 return false; 03162 } 03163 03164 /* Calculate norm(M). */ 03165 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 03166 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 03167 03168 /* Calculate objective function. */ 03169 obj = a * b.raise( f ) * c.raise( g ); 03170 03171 /* Calculate the derivative of the objective function. */ 03172 f = b.value() * obj / f; /* Constant on nabla f */ 03173 g = c.value() * obj / g; /* Constant on nable g */ 03174 f *= 2.0; /* Modification for nabla f */ 03175 03176 adj_m[0] = matr[0] * f + loc1 * g; 03177 adj_m[1] = matr[1] * f + loc2 * g; 03178 adj_m[2] = matr[2] * f + loc3 * g; 03179 03180 loc1 = matr[0] * g; 03181 loc2 = matr[1] * g; 03182 loc3 = matr[2] * g; 03183 03184 adj_m[3] = matr[3] * f + loc3 * matr[7] - loc2 * matr[8]; 03185 adj_m[4] = matr[4] * f + loc1 * matr[8] - loc3 * matr[6]; 03186 adj_m[5] = matr[5] * f + loc2 * matr[6] - loc1 * matr[7]; 03187 03188 adj_m[6] = matr[6] * f + loc2 * matr[5] - loc3 * matr[4]; 03189 adj_m[7] = matr[7] * f + loc3 * matr[3] - loc1 * matr[5]; 03190 adj_m[8] = matr[8] * f + loc1 * matr[4] - loc2 * matr[3]; 03191 03192 g_obj[0][0] = -adj_m[0] - isqrt3 * adj_m[1] - adj_m[2]; 03193 g_obj[1][0] = adj_m[0] - isqrt3 * adj_m[1]; 03194 g_obj[2][0] = tisqrt3 * adj_m[1]; 03195 g_obj[3][0] = adj_m[2]; 03196 03197 g_obj[0][1] = -adj_m[3] - isqrt3 * adj_m[4] - adj_m[5]; 03198 g_obj[1][1] = adj_m[3] - isqrt3 * adj_m[4]; 03199 g_obj[2][1] = tisqrt3 * adj_m[4]; 03200 g_obj[3][1] = adj_m[5]; 03201 03202 g_obj[0][2] = -adj_m[6] - isqrt3 * adj_m[7] - adj_m[8]; 03203 g_obj[1][2] = adj_m[6] - isqrt3 * adj_m[7]; 03204 g_obj[2][2] = tisqrt3 * adj_m[7]; 03205 g_obj[3][2] = adj_m[8]; 03206 03207 return true; 03208 } 03209 03210 inline bool h_fcn_3w( double& obj, 03211 Vector3D g_obj[4], 03212 Matrix3D h_obj[10], 03213 const Vector3D x[4], 03214 const double a, 03215 const Exponent& b, 03216 const Exponent& c ) 03217 { 03218 double matr[9], f; 03219 double adj_m[9], g; 03220 double dg[9], loc0, loc1, loc2, loc3, loc4; 03221 double A[12], J_A[6], J_B[9], J_C[9], cross; 03222 03223 /* Calculate M = A*inv(W). */ 03224 matr[0] = x[1][0] - x[0][0]; 03225 matr[1] = isqrt3 * ( 2 * x[2][0] - x[1][0] - x[0][0] ); 03226 matr[2] = x[3][0] - x[0][0]; 03227 03228 matr[3] = x[1][1] - x[0][1]; 03229 matr[4] = isqrt3 * ( 2 * x[2][1] - x[1][1] - x[0][1] ); 03230 matr[5] = x[3][1] - x[0][1]; 03231 03232 matr[6] = x[1][2] - x[0][2]; 03233 matr[7] = isqrt3 * ( 2 * x[2][2] - x[1][2] - x[0][2] ); 03234 matr[8] = x[3][2] - x[0][2]; 03235 03236 /* Calculate det(M). */ 03237 dg[0] = matr[4] * matr[8] - matr[5] * matr[7]; 03238 dg[1] = matr[5] * matr[6] - matr[3] * matr[8]; 03239 dg[2] = matr[3] * matr[7] - matr[4] * matr[6]; 03240 g = matr[0] * dg[0] + matr[1] * dg[1] + matr[2] * dg[2]; 03241 if( g < MSQ_MIN ) 03242 { 03243 obj = g; 03244 return false; 03245 } 03246 03247 dg[3] = matr[2] * matr[7] - matr[1] * matr[8]; 03248 dg[4] = matr[0] * matr[8] - matr[2] * matr[6]; 03249 dg[5] = matr[1] * matr[6] - matr[0] * matr[7]; 03250 dg[6] = matr[1] * matr[5] - matr[2] * matr[4]; 03251 dg[7] = matr[2] * matr[3] - matr[0] * matr[5]; 03252 dg[8] = matr[0] * matr[4] - matr[1] * matr[3]; 03253 03254 /* Calculate norm(M). */ 03255 f = matr[0] * matr[0] + matr[1] * matr[1] + matr[2] * matr[2] + matr[3] * matr[3] + matr[4] * matr[4] + 03256 matr[5] * matr[5] + matr[6] * matr[6] + matr[7] * matr[7] + matr[8] * matr[8]; 03257 03258 loc3 = f; 03259 loc4 = g; 03260 03261 /* Calculate objective function. */ 03262 obj = a * b.raise( f ) * c.raise( g ); 03263 03264 /* Calculate the derivative of the objective function. */ 03265 f = b.value() * obj / f; /* Constant on nabla f */ 03266 g = c.value() * obj / g; /* Constant on nable g */ 03267 f *= 2.0; /* Modification for nabla f */ 03268 03269 adj_m[0] = matr[0] * f + dg[0] * g; 03270 adj_m[1] = matr[1] * f + dg[1] * g; 03271 adj_m[2] = matr[2] * f + dg[2] * g; 03272 adj_m[3] = matr[3] * f + dg[3] * g; 03273 adj_m[4] = matr[4] * f + dg[4] * g; 03274 adj_m[5] = matr[5] * f + dg[5] * g; 03275 adj_m[6] = matr[6] * f + dg[6] * g; 03276 adj_m[7] = matr[7] * f + dg[7] * g; 03277 adj_m[8] = matr[8] * f + dg[8] * g; 03278 03279 g_obj[0][0] = -adj_m[0] - isqrt3 * adj_m[1] - adj_m[2]; 03280 g_obj[1][0] = adj_m[0] - isqrt3 * adj_m[1]; 03281 g_obj[2][0] = tisqrt3 * adj_m[1]; 03282 g_obj[3][0] = adj_m[2]; 03283 03284 g_obj[0][1] = -adj_m[3] - isqrt3 * adj_m[4] - adj_m[5]; 03285 g_obj[1][1] = adj_m[3] - isqrt3 * adj_m[4]; 03286 g_obj[2][1] = tisqrt3 * adj_m[4]; 03287 g_obj[3][1] = adj_m[5]; 03288 03289 g_obj[0][2] = -adj_m[6] - isqrt3 * adj_m[7] - adj_m[8]; 03290 g_obj[1][2] = adj_m[6] - isqrt3 * adj_m[7]; 03291 g_obj[2][2] = tisqrt3 * adj_m[7]; 03292 g_obj[3][2] = adj_m[8]; 03293 03294 /* Calculate the hessian of the objective. */ 03295 loc0 = f; /* Constant on nabla^2 f */ 03296 loc1 = g; /* Constant on nabla^2 g */ 03297 cross = f * c.value() / loc4; /* Constant on nabla g nabla f */ 03298 f = f * ( b.value() - 1 ) / loc3; /* Constant on nabla f nabla f */ 03299 g = g * ( c.value() - 1 ) / loc4; /* Constant on nabla g nabla g */ 03300 f *= 2.0; /* Modification for nabla f */ 03301 03302 /* First block of rows */ 03303 loc3 = matr[0] * f + dg[0] * cross; 03304 loc4 = dg[0] * g + matr[0] * cross; 03305 03306 J_A[0] = loc0 + loc3 * matr[0] + loc4 * dg[0]; 03307 J_A[1] = loc3 * matr[1] + loc4 * dg[1]; 03308 J_A[2] = loc3 * matr[2] + loc4 * dg[2]; 03309 J_B[0] = loc3 * matr[3] + loc4 * dg[3]; 03310 J_B[1] = loc3 * matr[4] + loc4 * dg[4]; 03311 J_B[2] = loc3 * matr[5] + loc4 * dg[5]; 03312 J_C[0] = loc3 * matr[6] + loc4 * dg[6]; 03313 J_C[1] = loc3 * matr[7] + loc4 * dg[7]; 03314 J_C[2] = loc3 * matr[8] + loc4 * dg[8]; 03315 03316 loc3 = matr[1] * f + dg[1] * cross; 03317 loc4 = dg[1] * g + matr[1] * cross; 03318 03319 J_A[3] = loc0 + loc3 * matr[1] + loc4 * dg[1]; 03320 J_A[4] = loc3 * matr[2] + loc4 * dg[2]; 03321 J_B[3] = loc3 * matr[3] + loc4 * dg[3]; 03322 J_B[4] = loc3 * matr[4] + loc4 * dg[4]; 03323 J_B[5] = loc3 * matr[5] + loc4 * dg[5]; 03324 J_C[3] = loc3 * matr[6] + loc4 * dg[6]; 03325 J_C[4] = loc3 * matr[7] + loc4 * dg[7]; 03326 J_C[5] = loc3 * matr[8] + loc4 * dg[8]; 03327 03328 loc3 = matr[2] * f + dg[2] * cross; 03329 loc4 = dg[2] * g + matr[2] * cross; 03330 03331 J_A[5] = loc0 + loc3 * matr[2] + loc4 * dg[2]; 03332 J_B[6] = loc3 * matr[3] + loc4 * dg[3]; 03333 J_B[7] = loc3 * matr[4] + loc4 * dg[4]; 03334 J_B[8] = loc3 * matr[5] + loc4 * dg[5]; 03335 J_C[6] = loc3 * matr[6] + loc4 * dg[6]; 03336 J_C[7] = loc3 * matr[7] + loc4 * dg[7]; 03337 J_C[8] = loc3 * matr[8] + loc4 * dg[8]; 03338 03339 /* First diagonal block */ 03340 A[0] = -J_A[0] - isqrt3 * J_A[1] - J_A[2]; 03341 A[1] = J_A[0] - isqrt3 * J_A[1]; 03342 // A[2] = tisqrt3*J_A[1]; 03343 // A[3] = J_A[2]; 03344 03345 A[4] = -J_A[1] - isqrt3 * J_A[3] - J_A[4]; 03346 A[5] = J_A[1] - isqrt3 * J_A[3]; 03347 A[6] = tisqrt3 * J_A[3]; 03348 // A[7] = J_A[4]; 03349 03350 A[8] = -J_A[2] - isqrt3 * J_A[4] - J_A[5]; 03351 A[9] = J_A[2] - isqrt3 * J_A[4]; 03352 A[10] = tisqrt3 * J_A[4]; 03353 A[11] = J_A[5]; 03354 03355 h_obj[0][0][0] = -A[0] - isqrt3 * A[4] - A[8]; 03356 h_obj[1][0][0] = A[0] - isqrt3 * A[4]; 03357 h_obj[2][0][0] = tisqrt3 * A[4]; 03358 h_obj[3][0][0] = A[8]; 03359 03360 h_obj[4][0][0] = A[1] - isqrt3 * A[5]; 03361 h_obj[5][0][0] = tisqrt3 * A[5]; 03362 h_obj[6][0][0] = A[9]; 03363 03364 h_obj[7][0][0] = tisqrt3 * A[6]; 03365 h_obj[8][0][0] = A[10]; 03366 03367 h_obj[9][0][0] = A[11]; 03368 03369 /* First off-diagonal block */ 03370 loc2 = matr[8] * loc1; 03371 J_B[1] += loc2; 03372 J_B[3] -= loc2; 03373 03374 loc2 = matr[7] * loc1; 03375 J_B[2] -= loc2; 03376 J_B[6] += loc2; 03377 03378 loc2 = matr[6] * loc1; 03379 J_B[5] += loc2; 03380 J_B[7] -= loc2; 03381 03382 A[0] = -J_B[0] - isqrt3 * J_B[1] - J_B[2]; 03383 A[1] = J_B[0] - isqrt3 * J_B[1]; 03384 A[2] = tisqrt3 * J_B[1]; 03385 A[3] = J_B[2]; 03386 03387 A[4] = -J_B[3] - isqrt3 * J_B[4] - J_B[5]; 03388 A[5] = J_B[3] - isqrt3 * J_B[4]; 03389 A[6] = tisqrt3 * J_B[4]; 03390 A[7] = J_B[5]; 03391 03392 A[8] = -J_B[6] - isqrt3 * J_B[7] - J_B[8]; 03393 A[9] = J_B[6] - isqrt3 * J_B[7]; 03394 A[10] = tisqrt3 * J_B[7]; 03395 A[11] = J_B[8]; 03396 03397 h_obj[0][0][1] = -A[0] - isqrt3 * A[4] - A[8]; 03398 h_obj[1][1][0] = A[0] - isqrt3 * A[4]; 03399 h_obj[2][1][0] = tisqrt3 * A[4]; 03400 h_obj[3][1][0] = A[8]; 03401 03402 h_obj[1][0][1] = -A[1] - isqrt3 * A[5] - A[9]; 03403 h_obj[4][0][1] = A[1] - isqrt3 * A[5]; 03404 h_obj[5][1][0] = tisqrt3 * A[5]; 03405 h_obj[6][1][0] = A[9]; 03406 03407 h_obj[2][0][1] = -A[2] - isqrt3 * A[6] - A[10]; 03408 h_obj[5][0][1] = A[2] - isqrt3 * A[6]; 03409 h_obj[7][0][1] = tisqrt3 * A[6]; 03410 h_obj[8][1][0] = A[10]; 03411 03412 h_obj[3][0][1] = -A[3] - isqrt3 * A[7] - A[11]; 03413 h_obj[6][0][1] = A[3] - isqrt3 * A[7]; 03414 h_obj[8][0][1] = tisqrt3 * A[7]; 03415 h_obj[9][0][1] = A[11]; 03416 03417 /* Second off-diagonal block */ 03418 loc2 = matr[5] * loc1; 03419 J_C[1] -= loc2; 03420 J_C[3] += loc2; 03421 03422 loc2 = matr[4] * loc1; 03423 J_C[2] += loc2; 03424 J_C[6] -= loc2; 03425 03426 loc2 = matr[3] * loc1; 03427 J_C[5] -= loc2; 03428 J_C[7] += loc2; 03429 03430 A[0] = -J_C[0] - isqrt3 * J_C[1] - J_C[2]; 03431 A[1] = J_C[0] - isqrt3 * J_C[1]; 03432 A[2] = tisqrt3 * J_C[1]; 03433 A[3] = J_C[2]; 03434 03435 A[4] = -J_C[3] - isqrt3 * J_C[4] - J_C[5]; 03436 A[5] = J_C[3] - isqrt3 * J_C[4]; 03437 A[6] = tisqrt3 * J_C[4]; 03438 A[7] = J_C[5]; 03439 03440 A[8] = -J_C[6] - isqrt3 * J_C[7] - J_C[8]; 03441 A[9] = J_C[6] - isqrt3 * J_C[7]; 03442 A[10] = tisqrt3 * J_C[7]; 03443 A[11] = J_C[8]; 03444 03445 h_obj[0][0][2] = -A[0] - isqrt3 * A[4] - A[8]; 03446 h_obj[1][2][0] = A[0] - isqrt3 * A[4]; 03447 h_obj[2][2][0] = tisqrt3 * A[4]; 03448 h_obj[3][2][0] = A[8]; 03449 03450 h_obj[1][0][2] = -A[1] - isqrt3 * A[5] - A[9]; 03451 h_obj[4][0][2] = A[1] - isqrt3 * A[5]; 03452 h_obj[5][2][0] = tisqrt3 * A[5]; 03453 h_obj[6][2][0] = A[9]; 03454 03455 h_obj[2][0][2] = -A[2] - isqrt3 * A[6] - A[10]; 03456 h_obj[5][0][2] = A[2] - isqrt3 * A[6]; 03457 h_obj[7][0][2] = tisqrt3 * A[6]; 03458 h_obj[8][2][0] = A[10]; 03459 03460 h_obj[3][0][2] = -A[3] - isqrt3 * A[7] - A[11]; 03461 h_obj[6][0][2] = A[3] - isqrt3 * A[7]; 03462 h_obj[8][0][2] = tisqrt3 * A[7]; 03463 h_obj[9][0][2] = A[11]; 03464 03465 /* Second block of rows */ 03466 loc3 = matr[3] * f + dg[3] * cross; 03467 loc4 = dg[3] * g + matr[3] * cross; 03468 03469 J_A[0] = loc0 + loc3 * matr[3] + loc4 * dg[3]; 03470 J_A[1] = loc3 * matr[4] + loc4 * dg[4]; 03471 J_A[2] = loc3 * matr[5] + loc4 * dg[5]; 03472 J_B[0] = loc3 * matr[6] + loc4 * dg[6]; 03473 J_B[1] = loc3 * matr[7] + loc4 * dg[7]; 03474 J_B[2] = loc3 * matr[8] + loc4 * dg[8]; 03475 03476 loc3 = matr[4] * f + dg[4] * cross; 03477 loc4 = dg[4] * g + matr[4] * cross; 03478 03479 J_A[3] = loc0 + loc3 * matr[4] + loc4 * dg[4]; 03480 J_A[4] = loc3 * matr[5] + loc4 * dg[5]; 03481 J_B[3] = loc3 * matr[6] + loc4 * dg[6]; 03482 J_B[4] = loc3 * matr[7] + loc4 * dg[7]; 03483 J_B[5] = loc3 * matr[8] + loc4 * dg[8]; 03484 03485 loc3 = matr[5] * f + dg[5] * cross; 03486 loc4 = dg[5] * g + matr[5] * cross; 03487 03488 J_A[5] = loc0 + loc3 * matr[5] + loc4 * dg[5]; 03489 J_B[6] = loc3 * matr[6] + loc4 * dg[6]; 03490 J_B[7] = loc3 * matr[7] + loc4 * dg[7]; 03491 J_B[8] = loc3 * matr[8] + loc4 * dg[8]; 03492 03493 /* Second diagonal block */ 03494 A[0] = -J_A[0] - isqrt3 * J_A[1] - J_A[2]; 03495 A[1] = J_A[0] - isqrt3 * J_A[1]; 03496 // A[2] = tisqrt3*J_A[1]; 03497 // A[3] = J_A[2]; 03498 03499 A[4] = -J_A[1] - isqrt3 * J_A[3] - J_A[4]; 03500 A[5] = J_A[1] - isqrt3 * J_A[3]; 03501 A[6] = tisqrt3 * J_A[3]; 03502 // A[7] = J_A[4]; 03503 03504 A[8] = -J_A[2] - isqrt3 * J_A[4] - J_A[5]; 03505 A[9] = J_A[2] - isqrt3 * J_A[4]; 03506 A[10] = tisqrt3 * J_A[4]; 03507 A[11] = J_A[5]; 03508 03509 h_obj[0][1][1] = -A[0] - isqrt3 * A[4] - A[8]; 03510 h_obj[1][1][1] = A[0] - isqrt3 * A[4]; 03511 h_obj[2][1][1] = tisqrt3 * A[4]; 03512 h_obj[3][1][1] = A[8]; 03513 03514 h_obj[4][1][1] = A[1] - isqrt3 * A[5]; 03515 h_obj[5][1][1] = tisqrt3 * A[5]; 03516 h_obj[6][1][1] = A[9]; 03517 03518 h_obj[7][1][1] = tisqrt3 * A[6]; 03519 h_obj[8][1][1] = A[10]; 03520 03521 h_obj[9][1][1] = A[11]; 03522 03523 /* Third off-diagonal block */ 03524 loc2 = matr[2] * loc1; 03525 J_B[1] += loc2; 03526 J_B[3] -= loc2; 03527 03528 loc2 = matr[1] * loc1; 03529 J_B[2] -= loc2; 03530 J_B[6] += loc2; 03531 03532 loc2 = matr[0] * loc1; 03533 J_B[5] += loc2; 03534 J_B[7] -= loc2; 03535 03536 A[0] = -J_B[0] - isqrt3 * J_B[1] - J_B[2]; 03537 A[1] = J_B[0] - isqrt3 * J_B[1]; 03538 A[2] = tisqrt3 * J_B[1]; 03539 A[3] = J_B[2]; 03540 03541 A[4] = -J_B[3] - isqrt3 * J_B[4] - J_B[5]; 03542 A[5] = J_B[3] - isqrt3 * J_B[4]; 03543 A[6] = tisqrt3 * J_B[4]; 03544 A[7] = J_B[5]; 03545 03546 A[8] = -J_B[6] - isqrt3 * J_B[7] - J_B[8]; 03547 A[9] = J_B[6] - isqrt3 * J_B[7]; 03548 A[10] = tisqrt3 * J_B[7]; 03549 A[11] = J_B[8]; 03550 03551 h_obj[0][1][2] = -A[0] - isqrt3 * A[4] - A[8]; 03552 h_obj[1][2][1] = A[0] - isqrt3 * A[4]; 03553 h_obj[2][2][1] = tisqrt3 * A[4]; 03554 h_obj[3][2][1] = A[8]; 03555 03556 h_obj[1][1][2] = -A[1] - isqrt3 * A[5] - A[9]; 03557 h_obj[4][1][2] = A[1] - isqrt3 * A[5]; 03558 h_obj[5][2][1] = tisqrt3 * A[5]; 03559 h_obj[6][2][1] = A[9]; 03560 03561 h_obj[2][1][2] = -A[2] - isqrt3 * A[6] - A[10]; 03562 h_obj[5][1][2] = A[2] - isqrt3 * A[6]; 03563 h_obj[7][1][2] = tisqrt3 * A[6]; 03564 h_obj[8][2][1] = A[10]; 03565 03566 h_obj[3][1][2] = -A[3] - isqrt3 * A[7] - A[11]; 03567 h_obj[6][1][2] = A[3] - isqrt3 * A[7]; 03568 h_obj[8][1][2] = tisqrt3 * A[7]; 03569 h_obj[9][1][2] = A[11]; 03570 03571 /* Third block of rows */ 03572 loc3 = matr[6] * f + dg[6] * cross; 03573 loc4 = dg[6] * g + matr[6] * cross; 03574 03575 J_A[0] = loc0 + loc3 * matr[6] + loc4 * dg[6]; 03576 J_A[1] = loc3 * matr[7] + loc4 * dg[7]; 03577 J_A[2] = loc3 * matr[8] + loc4 * dg[8]; 03578 03579 loc3 = matr[7] * f + dg[7] * cross; 03580 loc4 = dg[7] * g + matr[7] * cross; 03581 03582 J_A[3] = loc0 + loc3 * matr[7] + loc4 * dg[7]; 03583 J_A[4] = loc3 * matr[8] + loc4 * dg[8]; 03584 03585 loc3 = matr[8] * f + dg[8] * cross; 03586 loc4 = dg[8] * g + matr[8] * cross; 03587 03588 J_A[5] = loc0 + loc3 * matr[8] + loc4 * dg[8]; 03589 03590 /* Third diagonal block */ 03591 A[0] = -J_A[0] - isqrt3 * J_A[1] - J_A[2]; 03592 A[1] = J_A[0] - isqrt3 * J_A[1]; 03593 // A[2] = tisqrt3*J_A[1]; 03594 // A[3] = J_A[2]; 03595 03596 A[4] = -J_A[1] - isqrt3 * J_A[3] - J_A[4]; 03597 A[5] = J_A[1] - isqrt3 * J_A[3]; 03598 A[6] = tisqrt3 * J_A[3]; 03599 // A[7] = J_A[4]; 03600 03601 A[8] = -J_A[2] - isqrt3 * J_A[4] - J_A[5]; 03602 A[9] = J_A[2] - isqrt3 * J_A[4]; 03603 A[10] = tisqrt3 * J_A[4]; 03604 A[11] = J_A[5]; 03605 03606 h_obj[0][2][2] = -A[0] - isqrt3 * A[4] - A[8]; 03607 h_obj[1][2][2] = A[0] - isqrt3 * A[4]; 03608 h_obj[2][2][2] = tisqrt3 * A[4]; 03609 h_obj[3][2][2] = A[8]; 03610 03611 h_obj[4][2][2] = A[1] - isqrt3 * A[5]; 03612 h_obj[5][2][2] = tisqrt3 * A[5]; 03613 h_obj[6][2][2] = A[9]; 03614 03615 h_obj[7][2][2] = tisqrt3 * A[6]; 03616 h_obj[8][2][2] = A[10]; 03617 03618 h_obj[9][2][2] = A[11]; 03619 03620 // completes diagonal blocks. 03621 h_obj[0].fill_lower_triangle(); 03622 h_obj[4].fill_lower_triangle(); 03623 h_obj[7].fill_lower_triangle(); 03624 h_obj[9].fill_lower_triangle(); 03625 03626 return true; 03627 } 03628 03629 } // namespace MBMesquite 03630 03631 #endif