1 /* *****************************************************************
2     MESQUITE -- The Mesh Quality Improvement Toolkit
3 
4     Copyright 2004 Sandia Corporation and Argonne National
5     Laboratory.  Under the terms of Contract DE-AC04-94AL85000
6     with Sandia Corporation, the U.S. Government retains certain
7     rights in 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     diachin2@llnl.gov, djmelan@sandia.gov, mbrewer@sandia.gov,
24     pknupp@sandia.gov, tleurent@mcs.anl.gov, tmunson@mcs.anl.gov
25 
26   ***************************************************************** */
27 // -*- Mode : c++; tab-width: 3; c-tab-always-indent: t; indent-tabs-mode: nil; c-basic-offset: 3 -*-
28 
29 /*! \file LPtoPTemplate.hpp
30   \brief Header file for the MBMesquite::LPtoPTemplate class
31  \author Michael Brewer
32  \author Thomas Leurent
33   \date   2002-05-23
34  */
35 
36 
37 #ifndef LPtoPTemplate_hpp
38 #define LPtoPTemplate_hpp
39 
40 #include "Mesquite.hpp"
41 #include "ObjectiveFunctionTemplate.hpp"
42 
43 namespace MBMesquite
44 {
45   class Matrix3D;
46 
47      /*! \class LPtoPTemplate
48        \brief Calculates the L_p objective function raised to the pth
49        power.  That is, sums the p_th powers of (the absolute value of)
50        the quality metric values.
51 
52        \todo MB. Suggestions made by Todd Munson:
53        a)  There is an inconsistent use of fabs.  The hessian evaluation
54        when using the one norm does not take the absolute value, while the
55        gradient does.
56        b)  The analytic gradient and hessian evaluations are incorrect when
57        the quality metric changes sign due to taking the absolute value.
58        The negative of the element gradient and hessian also needs to be
59        taken.
60        c)  Done.  The analytic gradient and hessian evaluations are
61        incorrect when the negate flag is set to -1.  The negative
62        of the element gradient and hessian also needs to be taken
63        in this case.
64        d)  The malloc in the concrete_eval routine should be removed.
65 
66      */
67   class LPtoPTemplate :public ObjectiveFunctionTemplate
68   {
69   public:
70 	MESQUITE_EXPORT
71     LPtoPTemplate(QualityMetric *, short, MsqError &);
72 	MESQUITE_EXPORT
73     LPtoPTemplate( short, QualityMetric* );
74 
75 	MESQUITE_EXPORT
76     virtual ~LPtoPTemplate();
77 
78 	MESQUITE_EXPORT
79     virtual void clear();
80 
81 	MESQUITE_EXPORT
82     virtual bool evaluate( EvalType type,
83                            PatchData& pd,
84                            double& value_out,
85                            bool free,
86                            MsqError& err );
87 
88 	MESQUITE_EXPORT
89     virtual bool evaluate_with_gradient( EvalType type,
90                                          PatchData& pd,
91                                          double& value_out,
92                                          std::vector<Vector3D>& grad_out,
93                                          MsqError& err );
94 
95 	MESQUITE_EXPORT
96     virtual bool evaluate_with_Hessian_diagonal( EvalType type,
97                                         PatchData& pd,
98                                         double& value_out,
99                                         std::vector<Vector3D>& grad_out,
100                                         std::vector<SymMatrix3D>& hess_diag_out,
101                                         MsqError& err );
102 
103 	MESQUITE_EXPORT
104     virtual bool evaluate_with_Hessian( EvalType type,
105                                         PatchData& pd,
106                                         double& value_out,
107                                         std::vector<Vector3D>& grad_out,
108                                         MsqHessian& Hessian_out,
109                                         MsqError& err );
110 
111 	MESQUITE_EXPORT
112     virtual ObjectiveFunction* clone() const;
113 
114        /*!Use set_dividing_by_n to control whether this objective
115          function divides it's final value by the number of
116          metric values used to compute the objective function
117          value.  That is, if the associated metric is element
118          based, the obejctive function value is divided by
119          the number of elements.  If it is vertex based, the
120          objective function is divided by the number of vertices.
121          If this function is passed 'true', the function value
122          will be scale.  If it is passed false, the function
123          value will not be scaled.*/
124 	MESQUITE_EXPORT
set_dividing_by_n(bool d_bool)125     void set_dividing_by_n(bool d_bool){dividingByN=d_bool;}
126 
127    private:
128      double get_value( double power_sum, size_t count, EvalType type,
129 		       size_t& global_count, MsqError& err );
130 
131        //! The metric value entries are raised to the pVal power
132      short pVal;
133        //! dividingByN is true if we are dividing the objective function
134        //! by the number of metric values.
135      bool dividingByN;
136 
137 
138      size_t mCount;    /**< The number of accumulated entires */
139      double mPowSum;   /**< The accumulated sum of values */
140      size_t saveCount; /**< Saved count from previous patch */
141      double savePowSum;/**< Saved sum from previous patch */
142 
143      /** Temporary storage for qm sample handles */
144      mutable std::vector<size_t> qmHandles;
145      /** Temporary storage for qm vertex indices */
146      mutable std::vector<size_t> mIndices;
147      /** Temporary storage for qm gradient */
148      mutable std::vector<Vector3D> mGradient;
149      /** Temporary storage for qm Hessian diagonal blocks */
150      mutable std::vector<SymMatrix3D> mDiag;
151       /** Temporary storage for qm Hessian */
152      mutable std::vector<Matrix3D> mHessian;
153    };
154 
155 }//namespace
156 
157 #endif // LPtoPTemplate_hpp
158 
159