1 /* *****************************************************************
2     MESQUITE -- The Mesh Quality Improvement Toolkit
3 
4     Copyright 2010 Sandia National Laboratories.  Developed at the
5     University of Wisconsin--Madison under SNL contract number
6     624796.  The U.S. Government and the University of Wisconsin
7     retain certain rights to this software.
8 
9     This library is free software; you can redistribute it and/or
10     modify it under the terms of the GNU Lesser General Public
11     License as published by the Free Software Foundation; either
12     version 2.1 of the License, or (at your option) any later version.
13 
14     This library is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17     Lesser General Public License for more details.
18 
19     You should have received a copy of the GNU Lesser General Public License
20     (lgpl.txt) along with this library; if not, write to the Free Software
21     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 
23     (2010) kraftche@cae.wisc.edu
24 
25   ***************************************************************** */
26 
27 
28 /** \file TMetric.hpp
29  *  \brief
30  *  \author Jason Kraftcheck
31  */
32 
33 #ifndef MSQ_T_METRIC_HPP
34 #define MSQ_T_METRIC_HPP
35 
36 #include "Mesquite.hpp"
37 #include <string>
38 
39 namespace MBMesquite {
40 
41 class MsqError;
42 template <unsigned R, unsigned C> class MsqMatrix;
43 
44 class TMetric
45 {
46 public:
47 
48   MESQUITE_EXPORT virtual
49   ~TMetric();
50 
51   MESQUITE_EXPORT virtual
52   std::string get_name() const = 0;
53 
54     /**\brief Evaluate \f$\mu(T)\f$
55      *
56      *\param T 2x2 relative measure matrix (typically A W^-1)
57      *\param result Output: value of function
58      *\return false if function cannot be evaluated for given T
59      *          (e.g. division by zero, etc.), true otherwise.
60      */
61   MESQUITE_EXPORT virtual
62   bool evaluate( const MsqMatrix<2,2>& T,
63                  double& result,
64                  MsqError& err );
65 
66     /**\brief Evaluate \f$\mu(T)\f$
67      *
68      *\param T 3x3 relative measure matrix (typically A W^-1)
69      *\param result Output: value of function
70      *\return false if function cannot be evaluated for given T
71      *          (e.g. division by zero, etc.), true otherwise.
72      */
73   MESQUITE_EXPORT virtual
74   bool evaluate( const MsqMatrix<3,3>& T,
75                  double& result,
76                  MsqError& err );
77 
78     /**\brief Gradient of \f$\mu(T)\f$ with respect to components of T
79      *
80      *\param T 2x2 relative measure matrix (typically A W^-1)
81      *\param result Output: value of function
82      *\param deriv_wrt_T Output: partial deriviatve of \f$\mu\f$ wrt each term of T,
83      *                           evaluated at passed T.
84      *                           \f[\left[\begin{array}{cc}
85      *                            \frac{\partial\mu}{\partial T_{0,0}} &
86      *                            \frac{\partial\mu}{\partial T_{0,1}} \\
87      *                            \frac{\partial\mu}{\partial T_{1,0}} &
88      *                            \frac{\partial\mu}{\partial T_{1,1}} \\
89      *                            \end{array}\right]\f]
90      *\return false if function cannot be evaluated for given T
91      *          (e.g. division by zero, etc.), true otherwise.
92      */
93   MESQUITE_EXPORT virtual
94   bool evaluate_with_grad( const MsqMatrix<2,2>& T,
95                            double& result,
96                            MsqMatrix<2,2>& deriv_wrt_T,
97                            MsqError& err );
98 
99     /**\brief Gradient of \f$\mu(T)\f$ with respect to components of T
100      *
101      *\param T 3x3 relative measure matrix (typically A W^-1)
102      *\param result Output: value of function
103      *\param deriv_wrt_T Output: partial deriviatve of \f$\mu\f$ wrt each term of T,
104      *                           evaluated at passed T.
105      *                           \f[\left[\begin{array}{ccc}
106      *                            \frac{\partial\mu}{\partial T_{0,0}} &
107      *                            \frac{\partial\mu}{\partial T_{0,1}} &
108      *                            \frac{\partial\mu}{\partial T_{0,2}} \\
109      *                            \frac{\partial\mu}{\partial T_{1,0}} &
110      *                            \frac{\partial\mu}{\partial T_{1,1}} &
111      *                            \frac{\partial\mu}{\partial T_{1,2}} \\
112      *                            \frac{\partial\mu}{\partial T_{2,0}} &
113      *                            \frac{\partial\mu}{\partial T_{2,1}} &
114      *                            \frac{\partial\mu}{\partial T_{2,2}}
115      *                            \end{array}\right]\f]
116      *\return false if function cannot be evaluated for given T
117      *          (e.g. division by zero, etc.), true otherwise.
118      */
119   MESQUITE_EXPORT virtual
120   bool evaluate_with_grad( const MsqMatrix<3,3>& T,
121                            double& result,
122                            MsqMatrix<3,3>& deriv_wrt_T,
123                            MsqError& err );
124 
125     /**\brief Hessian of \f$\mu(T)\f$ with respect to components of T
126      *
127      *\param T 3x3 relative measure matrix (typically A W^-1)
128      *\param result Output: value of function
129      *\param deriv_wrt_T Output: partial deriviatve of \f$\mu\f$ wrt each term of T,
130      *                           evaluated at passed T.
131      *\param second_wrt_T Output: 9x9 matrix of second partial deriviatve of \f$\mu\f$ wrt
132      *                           each term of T, in row-major order.  The symmetric
133      *                           matrix is decomposed into 3x3 blocks and only the upper diagonal
134      *                           blocks, in row-major order, are returned.
135      *                           \f[\left[\begin{array}{cc|cc}
136      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}^2} &
137      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial A_{0,1}} &
138      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial A_{1,0}} &
139      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial A_{1,1}} \\
140      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial A_{0,1}} &
141      *                           \frac{\partial^{2}\mu}{\partial T_{0,1}^2} &
142      *                           \frac{\partial^{2}\mu}{\partial T_{0,1}\partial A_{1,0}} &
143      *                           \frac{\partial^{2}\mu}{\partial T_{0,1}\partial A_{1,1}} \\
144      *                           \hline & &
145      *                           \frac{\partial^{2}\mu}{\partial T_{1,0}^2} &
146      *                           \frac{\partial^{2}\mu}{\partial T_{1,0}\partial A_{1,1}} \\
147      *                           & &
148      *                           \frac{\partial^{2}\mu}{\partial T_{1,0}\partial A_{1,1}} &
149      *                           \frac{\partial^{2}\mu}{\partial T_{1,1}^2} \\
150      *                            \end{array}\right]\f]
151      *
152      *\return false if function cannot be evaluated for given T
153      *          (e.g. division by zero, etc.), true otherwise.
154      */
155   MESQUITE_EXPORT virtual
156   bool evaluate_with_hess( const MsqMatrix<2,2>& T,
157                            double& result,
158                            MsqMatrix<2,2>& deriv_wrt_T,
159                            MsqMatrix<2,2> second_wrt_T[3],
160                            MsqError& err );
161     /**\brief Hessian of \f$\mu(T)\f$ with respect to components of T
162      *
163      *\param T 3x3 relative measure matrix (typically A W^-1)
164      *\param result Output: value of function
165      *\param deriv_wrt_T Output: partial deriviatve of \f$\mu\f$ wrt each term of T,
166      *                           evaluated at passed T.
167      *\param second_wrt_T Output: 9x9 matrix of second partial deriviatve of \f$\mu\f$ wrt
168      *                           each term of T, in row-major order.  The symmetric
169      *                           matrix is decomposed into 3x3 blocks and only the upper diagonal
170      *                           blocks, in row-major order, are returned.
171      *                           \f[\left[\begin{array}{ccc|ccc|ccc}
172      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}^2} &
173      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial T_{0,1}} &
174      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial T_{0,2}} &
175      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial T_{1,0}} &
176      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial T_{1,1}} &
177      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial T_{1,2}} &
178      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial T_{2,0}} &
179      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial T_{2,1}} &
180      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial T_{2,2}} \\
181      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial T_{0,1}} &
182      *                           \frac{\partial^{2}\mu}{\partial T_{0,1}^2} &
183      *                           \frac{\partial^{2}\mu}{\partial T_{0,1}\partial T_{0,2}} &
184      *                           \frac{\partial^{2}\mu}{\partial T_{0,1}\partial T_{1,0}} &
185      *                           \frac{\partial^{2}\mu}{\partial T_{0,1}\partial T_{1,1}} &
186      *                           \frac{\partial^{2}\mu}{\partial T_{0,1}\partial T_{1,2}} &
187      *                           \frac{\partial^{2}\mu}{\partial T_{0,1}\partial T_{2,0}} &
188      *                           \frac{\partial^{2}\mu}{\partial T_{0,1}\partial T_{2,1}} &
189      *                           \frac{\partial^{2}\mu}{\partial T_{0,1}\partial T_{2,2}} \\
190      *                           \frac{\partial^{2}\mu}{\partial T_{0,0}\partial T_{0,2}} &
191      *                           \frac{\partial^{2}\mu}{\partial T_{0,1}\partial T_{0,2}} &
192      *                           \frac{\partial^{2}\mu}{\partial T_{0,2}^2} &
193      *                           \frac{\partial^{2}\mu}{\partial T_{0,2}\partial T_{1,0}} &
194      *                           \frac{\partial^{2}\mu}{\partial T_{0,2}\partial T_{1,1}} &
195      *                           \frac{\partial^{2}\mu}{\partial T_{0,2}\partial T_{1,2}} &
196      *                           \frac{\partial^{2}\mu}{\partial T_{0,2}\partial T_{2,0}} &
197      *                           \frac{\partial^{2}\mu}{\partial T_{0,2}\partial T_{2,1}} &
198      *                           \frac{\partial^{2}\mu}{\partial T_{0,2}\partial T_{2,2}} \\
199      *                           \hline & & &
200      *                           \frac{\partial^{2}\mu}{\partial T_{1,0}^2} &
201      *                           \frac{\partial^{2}\mu}{\partial T_{1,0}\partial T_{1,1}} &
202      *                           \frac{\partial^{2}\mu}{\partial T_{1,0}\partial T_{1,2}} &
203      *                           \frac{\partial^{2}\mu}{\partial T_{1,0}\partial T_{2,0}} &
204      *                           \frac{\partial^{2}\mu}{\partial T_{1,0}\partial T_{2,1}} &
205      *                           \frac{\partial^{2}\mu}{\partial T_{1,0}\partial T_{2,2}} \\
206      *                           & & &
207      *                           \frac{\partial^{2}\mu}{\partial T_{1,0}\partial T_{1,1}} &
208      *                           \frac{\partial^{2}\mu}{\partial T_{1,1}^2} &
209      *                           \frac{\partial^{2}\mu}{\partial T_{1,1}\partial T_{1,2}} &
210      *                           \frac{\partial^{2}\mu}{\partial T_{1,1}\partial T_{2,0}} &
211      *                           \frac{\partial^{2}\mu}{\partial T_{1,1}\partial T_{2,1}} &
212      *                           \frac{\partial^{2}\mu}{\partial T_{1,1}\partial T_{2,2}} \\
213      *                           & & &
214      *                           \frac{\partial^{2}\mu}{\partial T_{1,0}\partial T_{1,2}} &
215      *                           \frac{\partial^{2}\mu}{\partial T_{1,1}\partial T_{1,2}} &
216      *                           \frac{\partial^{2}\mu}{\partial T_{1,2}^2} &
217      *                           \frac{\partial^{2}\mu}{\partial T_{1,2}\partial T_{2,0}} &
218      *                           \frac{\partial^{2}\mu}{\partial T_{1,2}\partial T_{2,1}} &
219      *                           \frac{\partial^{2}\mu}{\partial T_{1,2}\partial T_{2,2}} \\
220      *                           \hline & & & & & &
221      *                           \frac{\partial^{2}\mu}{\partial T_{2,0}^2} &
222      *                           \frac{\partial^{2}\mu}{\partial T_{2,0}\partial T_{2,1}} &
223      *                           \frac{\partial^{2}\mu}{\partial T_{2,0}\partial T_{2,2}} \\
224      *                           & & & & & &
225      *                           \frac{\partial^{2}\mu}{\partial T_{2,0}\partial T_{2,1}} &
226      *                           \frac{\partial^{2}\mu}{\partial T_{2,1}^2} &
227      *                           \frac{\partial^{2}\mu}{\partial T_{2,1}\partial T_{2,2}} \\
228      *                           & & & & & &
229      *                           \frac{\partial^{2}\mu}{\partial T_{2,0}\partial T_{2,2}} &
230      *                           \frac{\partial^{2}\mu}{\partial T_{2,1}\partial T_{2,2}} &
231      *                           \frac{\partial^{2}\mu}{\partial T_{2,2}^2} \\
232      *                            \end{array}\right]\f]
233      *\return false if function cannot be evaluated for given T
234      *          (e.g. division by zero, etc.), true otherwise.
235      */
236   MESQUITE_EXPORT virtual
237   bool evaluate_with_hess( const MsqMatrix<3,3>& T,
238                            double& result,
239                            MsqMatrix<3,3>& deriv_wrt_T,
240                            MsqMatrix<3,3> second_wrt_T[6],
241                            MsqError& err );
242 
invalid_determinant(double d)243   static inline bool invalid_determinant( double d )
244     { return d < 1e-12; }
245 };
246 
247 class TMetric2D : public TMetric
248 {
249 public:
250 
251   MESQUITE_EXPORT virtual
252   ~TMetric2D();
253 
254     /**\brief Evaluate \f$\mu(T)\f$
255      *
256      * This method always returns an error for 2D-only metrics
257      */
258   MESQUITE_EXPORT virtual
259   bool evaluate( const MsqMatrix<3,3>& T,
260                  double& result,
261                  MsqError& err );
262 };
263 
264 class TMetric3D : public TMetric
265 {
266 public:
267 
268   MESQUITE_EXPORT virtual
269   ~TMetric3D();
270 
271     /**\brief Evaluate \f$\mu(T)\f$
272      *
273      * This method always returns an error for 3D-only metrics
274      */
275   MESQUITE_EXPORT virtual
276   bool evaluate( const MsqMatrix<2,2>& T,
277                  double& result,
278                  MsqError& err );
279 };
280 
281 
282 } // namespace MBMesquite
283 
284 #endif
285