MOAB: Mesh Oriented datABase  (version 5.2.1)
CompositeOFMultiply.cpp
Go to the documentation of this file.
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 /*!
00028   \file    CompositeOFMultiply.cpp
00029   \brief
00030 
00031   This Objective Function combines two Objective Functions by mulitplication
00032   \author Michael Brewer
00033   \date   2002-01-23
00034 */
00035 #include <cmath>
00036 #include "CompositeOFMultiply.hpp"
00037 #include "MsqTimer.hpp"
00038 #include "PatchData.hpp"
00039 
00040 namespace MBMesquite
00041 {
00042 
00043 /*!
00044 Sets the QualityMetric pointer to the metric associated with Obj1 and Obj2
00045 if Obj1 and Obj2 are associated with the same metric.  Otherwise, it sets
00046 the QualityMetric pointer to NULL.  The new
00047 ObjectiveFunction's negateFlag is set to negative one only if both Obj1 and
00048 Obj2's negateFlag are negative one (because obj1 and obj2's evaluate function
00049 multiply their return values by negative one if their respective
00050 function needs to be maximized.  If both of these functions needed to
00051 be maximized, then the negative ones will have cancelled out).  Otherwise,
00052 the negateFlag is set to one.  Defaults to the analytical gradient.
00053   \param Obj1 (ObjectiveFunction*)
00054   \param Obj2 (ObjectiveFunction*)
00055  */
00056 CompositeOFMultiply::CompositeOFMultiply( ObjectiveFunction* Obj1, ObjectiveFunction* Obj2, bool delete_OFs )
00057     : deleteObjFuncs( delete_OFs )
00058 {
00059     objFunc1 = Obj1;
00060     objFunc2 = Obj2;
00061 }
00062 
00063 // Michael:  need to clean up here
00064 CompositeOFMultiply::~CompositeOFMultiply()
00065 {
00066     if( deleteObjFuncs )
00067     {
00068         delete objFunc1;
00069         delete objFunc2;
00070     }
00071 }
00072 
00073 ObjectiveFunction* CompositeOFMultiply::clone() const
00074 {
00075     return new CompositeOFMultiply( objFunc1->clone(), objFunc2->clone(), true );
00076 }
00077 
00078 void CompositeOFMultiply::clear()
00079 {
00080     objFunc1->clear();
00081     objFunc2->clear();
00082 }
00083 
00084 void CompositeOFMultiply::initialize_queue( MeshDomainAssoc* mesh_and_domain, const Settings* settings, MsqError& err )
00085 {
00086     objFunc1->initialize_queue( mesh_and_domain, settings, err );MSQ_ERRRTN( err );
00087     objFunc2->initialize_queue( mesh_and_domain, settings, err );MSQ_ERRRTN( err );
00088 }
00089 
00090 bool CompositeOFMultiply::initialize_block_coordinate_descent( MeshDomainAssoc* mesh_and_domain,
00091                                                                const Settings* settings, PatchSet* user_set,
00092                                                                MsqError& err )
00093 {
00094     bool rval1, rval2;
00095     rval1 = objFunc1->initialize_block_coordinate_descent( mesh_and_domain, settings, user_set, err );
00096     MSQ_ERRZERO( err );
00097     rval2 = objFunc2->initialize_block_coordinate_descent( mesh_and_domain, settings, user_set, err );
00098     return !MSQ_CHKERR( err ) && rval1 && rval2;
00099 }
00100 
00101 bool CompositeOFMultiply::evaluate( EvalType type, PatchData& pd, double& value_out, bool free, MsqError& err )
00102 {
00103     double value_2;
00104     bool ok;
00105 
00106     ok = objFunc1->evaluate( type, pd, value_out, free, err );
00107     if( MSQ_CHKERR( err ) || !ok ) return false;
00108     ok = objFunc2->evaluate( type, pd, value_2, free, err );
00109     if( MSQ_CHKERR( err ) || !ok ) return false;
00110 
00111     value_out *= value_2;
00112     return true;
00113 }
00114 
00115 bool CompositeOFMultiply::evaluate_with_gradient( EvalType type, PatchData& pd, double& value_out,
00116                                                   std::vector< Vector3D >& grad_out, MsqError& err )
00117 {
00118     double value_2;
00119     bool ok;
00120 
00121     ok = objFunc1->evaluate_with_gradient( type, pd, value_out, grad_out, err );
00122     if( MSQ_CHKERR( err ) || !ok ) return false;
00123     ok = objFunc2->evaluate_with_gradient( type, pd, value_2, mGradient, err );
00124     if( MSQ_CHKERR( err ) || !ok ) return false;
00125 
00126     assert( grad_out.size() == pd.num_free_vertices() );
00127     assert( mGradient.size() == pd.num_free_vertices() );
00128 
00129     std::vector< Vector3D >::iterator i = grad_out.begin(), j = mGradient.begin();
00130     while( i != grad_out.end() )
00131     {
00132         *i *= value_2;
00133         *j *= value_out;
00134         *i += *j;
00135         ++i;
00136         ++j;
00137     }
00138     value_out *= value_2;
00139     return true;
00140 }
00141 
00142 bool CompositeOFMultiply::evaluate_with_Hessian_diagonal( EvalType type, PatchData& pd, double& value_out,
00143                                                           std::vector< Vector3D >& grad_out,
00144                                                           std::vector< SymMatrix3D >& diag_out, MsqError& err )
00145 {
00146     double value_2;
00147     bool valid;
00148 
00149     valid = objFunc1->evaluate_with_Hessian_diagonal( type, pd, value_out, grad_out, diag_out, err );
00150     if( MSQ_CHKERR( err ) || !valid ) return false;
00151     valid = objFunc2->evaluate_with_Hessian_diagonal( type, pd, value_2, mGradient, mDiagonal, err );
00152     if( MSQ_CHKERR( err ) || !valid ) return false;
00153 
00154     for( size_t i = 0; i < pd.num_free_vertices(); ++i )
00155     {
00156         diag_out[i] *= value_2;
00157         mDiagonal[i] *= value_out;
00158         diag_out[i] += mDiagonal[i];
00159         diag_out[i] += outer_plus_transpose( grad_out[i], mGradient[i] );
00160 
00161         grad_out[i] *= value_2;
00162         mGradient[i] *= value_out;
00163         grad_out[i] += mGradient[i];
00164     }
00165 
00166     value_out *= value_2;
00167     return true;
00168 }
00169 
00170 bool CompositeOFMultiply::evaluate_with_Hessian( EvalType, PatchData&, double&, std::vector< Vector3D >&, MsqHessian&,
00171                                                  MsqError& err )
00172 {
00173     MSQ_SETERR( err )
00174     ( "Mesquite is not capable of representing the dense "
00175       "Hessian of the product of two objective fuctions. "
00176       "Either choose a solver that does not require the "
00177       "Hessian of the objective function or do not use the "
00178       "CompositeOFMultiple objective function .",
00179       MsqError::INVALID_STATE );
00180     return false;
00181 }
00182 
00183 int CompositeOFMultiply::min_patch_layers() const
00184 {
00185     const int v1 = objFunc1->min_patch_layers();
00186     const int v2 = objFunc2->min_patch_layers();
00187     return v1 > v2 ? v1 : v2;
00188 }
00189 
00190 }  // namespace MBMesquite
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines