MOAB: Mesh Oriented datABase  (version 5.3.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     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    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, const Settings* settings,
00089                                                           PatchSet* user_set, MsqError& err )
00090 {
00091     bool rval1, rval2;
00092     rval1 = objFunc1->initialize_block_coordinate_descent( mesh_and_domain, settings, user_set, err );
00093     MSQ_ERRZERO( err );
00094     rval2 = objFunc2->initialize_block_coordinate_descent( mesh_and_domain, settings, user_set, err );
00095     return !MSQ_CHKERR( err ) && rval1 && rval2;
00096 }
00097 
00098 bool CompositeOFAdd::evaluate( EvalType type, PatchData& pd, double& value_out, bool free, MsqError& err )
00099 {
00100     double value_2;
00101     bool ok;
00102 
00103     ok = objFunc1->evaluate( type, pd, value_out, free, err );
00104     if( MSQ_CHKERR( err ) || !ok ) return false;
00105     ok = objFunc2->evaluate( type, pd, value_2, free, err );
00106     if( MSQ_CHKERR( err ) || !ok ) return false;
00107 
00108     value_out += value_2;
00109     return true;
00110 }
00111 
00112 bool CompositeOFAdd::evaluate_with_gradient( EvalType type, PatchData& pd, double& value_out,
00113                                              std::vector< Vector3D >& grad_out, MsqError& err )
00114 {
00115     double value_2;
00116     bool ok;
00117 
00118     ok = objFunc1->evaluate_with_gradient( type, pd, value_out, grad_out, err );
00119     if( MSQ_CHKERR( err ) || !ok ) return false;
00120     ok = objFunc2->evaluate_with_gradient( type, pd, value_2, mGradient, err );
00121     if( MSQ_CHKERR( err ) || !ok ) return false;
00122 
00123     assert( grad_out.size() == pd.num_free_vertices() );
00124     assert( mGradient.size() == pd.num_free_vertices() );
00125 
00126     std::vector< Vector3D >::iterator i = grad_out.begin(), j = mGradient.begin();
00127     while( i != grad_out.end() )
00128     {
00129         *i += *j;
00130         ++i;
00131         ++j;
00132     }
00133     value_out += value_2;
00134     return true;
00135 }
00136 
00137 bool CompositeOFAdd::evaluate_with_Hessian_diagonal( EvalType type, PatchData& pd, double& value_out,
00138                                                      std::vector< Vector3D >& grad_out,
00139                                                      std::vector< SymMatrix3D >& diag_out, MsqError& err )
00140 {
00141     double value_2;
00142     bool valid;
00143 
00144     valid = objFunc1->evaluate_with_Hessian_diagonal( type, pd, value_out, grad_out, diag_out, err );
00145     if( MSQ_CHKERR( err ) || !valid ) return false;
00146     valid = objFunc2->evaluate_with_Hessian_diagonal( type, pd, value_2, mGradient, mDiagonal, err );
00147     if( MSQ_CHKERR( err ) || !valid ) return false;
00148 
00149     for( size_t i = 0; i < pd.num_free_vertices(); ++i )
00150     {
00151         grad_out[i] += mGradient[i];
00152         diag_out[i] += mDiagonal[i];
00153     }
00154 
00155     value_out += value_2;
00156     return true;
00157 }
00158 
00159 bool CompositeOFAdd::evaluate_with_Hessian( EvalType type, PatchData& pd, double& value_out,
00160                                             std::vector< Vector3D >& grad_out, MsqHessian& Hessian_out, MsqError& err )
00161 {
00162     double value_2;
00163     bool ok;
00164 
00165     mHessian.initialize( Hessian_out );
00166 
00167     ok = objFunc1->evaluate_with_Hessian( type, pd, value_out, grad_out, Hessian_out, err );
00168     if( MSQ_CHKERR( err ) || !ok ) return false;
00169     ok = objFunc2->evaluate_with_Hessian( type, pd, value_2, mGradient, mHessian, err );
00170     if( MSQ_CHKERR( err ) || !ok ) return false;
00171 
00172     value_out += value_2;
00173 
00174     assert( grad_out.size() == pd.num_free_vertices() );
00175     assert( mGradient.size() == pd.num_free_vertices() );
00176 
00177     for( size_t i = 0; i < pd.num_free_vertices(); ++i )
00178         grad_out[i] += mGradient[i];
00179     Hessian_out.add( mHessian );
00180     return true;
00181 }
00182 
00183 int CompositeOFAdd::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