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