SundanceModelEvaluatorBase.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 // 
00007 // Copyright (year first published) Sandia Corporation.  Under the terms 
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 
00009 // retains certain rights in this software.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //                                                                                 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA                                                                                
00025 // Questions? Contact Kevin Long (krlong@sandia.gov), 
00026 // Sandia National Laboratories, Livermore, California, USA
00027 // 
00028 // ************************************************************************
00029 /* @HEADER@ */
00030 
00031 
00032 
00033 
00034 #include "SundanceOut.hpp"
00035 #include "SundanceTabs.hpp"
00036 #include "SundanceModelEvaluatorBase.hpp"
00037 
00038 #ifdef HAVE_SUNDANCE_MOOCHO
00039 #include "Thyra_DefaultSpmdVectorSpace.hpp"
00040 
00041 
00042 SundanceModelEvaluator
00043 ::SundanceModelEvaluator(const VectorType<double>& vecType)
00044   : vecType_(vecType), 
00045     objectiveSpace_(rcp(new Thyra::DefaultSpmdVectorSpace<double>(1)))
00046 {;}
00047 
00048 
00049 
00050 ModelEvaluatorBase::InArgs<double> SundanceModelEvaluator::createInArgs() const
00051 {
00052   ModelEvaluatorBase::InArgsSetup<double> inArgs;
00053   
00054   inArgs.setModelEvalDescription(description());
00055   /* Note: Np is the number of parameter *blocks*, not the number of parameters */
00056   inArgs.set_Np(1);
00057   inArgs.setSupports(IN_ARG_x, true);
00058 
00059   return inArgs;
00060 }
00061 
00062 
00063 
00064 
00065 ModelEvaluatorBase::OutArgs<double> SundanceModelEvaluator::createOutArgsImpl() const
00066 {
00067   ModelEvaluatorBase::OutArgsSetup<double> outArgs;
00068 
00069   outArgs.setModelEvalDescription(this->description());
00070   outArgs.set_Np_Ng(1,1);
00071   outArgs.setSupports(OUT_ARG_f,true);
00072   outArgs.setSupports(OUT_ARG_W_op,true);
00073   outArgs.set_W_properties(
00074     DerivativeProperties(
00075       DERIV_LINEARITY_NONCONST
00076       ,DERIV_RANK_FULL
00077       ,true // supportsAdjoint
00078       )
00079     );
00080   outArgs.setSupports(OUT_ARG_DfDp,0,DERIV_MV_BY_COL);
00081   outArgs.set_DfDp_properties(
00082     0,DerivativeProperties(
00083       DERIV_LINEARITY_NONCONST
00084       ,DERIV_RANK_DEFICIENT
00085       ,true // supportsAdjoint
00086       )
00087     );
00088   outArgs.setSupports(OUT_ARG_DgDx,0,DERIV_TRANS_MV_BY_ROW);
00089   outArgs.set_DgDx_properties(
00090     0,DerivativeProperties(
00091       DERIV_LINEARITY_NONCONST
00092       ,DERIV_RANK_DEFICIENT
00093       ,true // supportsAdjoint
00094       )
00095     );
00096   outArgs.setSupports(OUT_ARG_DgDp,0,0,DERIV_TRANS_MV_BY_ROW);
00097   outArgs.set_DgDp_properties(
00098     0,0,DerivativeProperties(
00099       DERIV_LINEARITY_NONCONST
00100       ,DERIV_RANK_DEFICIENT
00101       ,true // supportsAdjoint
00102       )
00103     );
00104   return outArgs;
00105 }
00106 
00107 ModelEvaluatorBase::InArgs<double>
00108 SundanceModelEvaluator::getNominalValues() const
00109 {
00110   typedef ModelEvaluatorBase MEB;
00111   MEB::InArgs<double> nominalValues = this->createInArgs();
00112   nominalValues.set_x(getInitialState().ptr());
00113   nominalValues.set_p(0,getInitialParameters().ptr());
00114   return nominalValues;
00115 }
00116 
00117 void SundanceModelEvaluator
00118 ::evalModelImpl(const ModelEvaluatorBase::InArgs<double>& inArgs,
00119             const ModelEvaluatorBase::OutArgs<double>& outArgs) const
00120 {
00121   Tabs tabs;
00122   if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tabs << 
00123                        "------------------calling eval model -----------------------");
00124   /* read input args. The const casts are needed until ConstVector is ready */
00125   TSFExtended::Vector<double> x = rcp_const_cast<VectorBase<double> >(inArgs.get_x());
00126 
00127   TSFExtended::Vector<double> p = rcp_const_cast<VectorBase<double> >(inArgs.get_p(0));
00128 
00129 
00130   /* Get objects into which the output value will be written */
00131 
00132   /* constraint residual */
00133   TSFExtended::Vector<double> f = outArgs.get_f();
00134 
00135   /* objective function value */
00136   TSFExtended::Vector<double> g = outArgs.get_g(0);
00137 
00138   /* df/dx */
00139   TSFExtended::LinearOperator<double> df_dx = 
00140     rcp_dynamic_cast<LinearOpBase<double> >(outArgs.get_W_op());
00141   
00142   if (outArgs.get_W_op().get()!=0) 
00143     {
00144       TEST_FOR_EXCEPTION(df_dx.ptr().get()==0, RuntimeError,  
00145                          "W_op is non-null but could not be cast to "
00146                          "a SingleScalarTypeOpBase<double>");
00147     }
00148   
00149 
00150   /* df/dp */
00151   RCP<MultiVectorBase<double> > df_dp_mv 
00152     = outArgs.get_DfDp(0).getDerivativeMultiVector().getMultiVector();
00153   Array<Vector<double> > df_dp(get_p_space(0)->dim());
00154   if (df_dp_mv.get() != 0)
00155     {
00156       for (int i=0; i<df_dp.size(); i++)
00157         {
00158           df_dp[i] = df_dp_mv->col(0);
00159         }
00160     }
00161 
00162   
00163 
00164   /* dg/dp */
00165   RCP<MultiVectorBase<double> > dg_dp_trans_mv 
00166     = outArgs.get_DgDp(0,0).getDerivativeMultiVector().getMultiVector();
00167   Vector<double> dg_dp_T;
00168   if (dg_dp_trans_mv.get() != 0)
00169     {
00170       dg_dp_T = dg_dp_trans_mv->col(0);
00171     }
00172 
00173   /* dg/dx */
00174   RCP<MultiVectorBase<double> > dg_dx_trans_mv 
00175     = outArgs.get_DgDx(0).getDerivativeMultiVector().getMultiVector();
00176   Vector<double> dg_dx_T;
00177   if (dg_dx_trans_mv.get() != 0)
00178     {
00179       dg_dx_T = dg_dx_trans_mv->col(0);
00180     }
00181 
00182 
00183   /* do the evaluation */
00184   double gVal;
00185   internalEvalModel(x, p, f, gVal, df_dx, df_dp, dg_dp_T, dg_dx_T);
00186 
00187   if (outArgs.get_W_op().get()!=0) 
00188     {
00189       TEST_FOR_EXCEPTION(df_dx.ptr().get()==0, RuntimeError,  
00190                          "W_op is non-null but could not be cast to a "
00191                          "SingleScalarTypeOpBase<double>");
00192     }
00193 
00194   /* Fill in objective function value */
00195   if ( g.ptr().get() != 0 )
00196     {
00197       Thyra::set_ele(0,gVal,g.ptr().get());
00198       // bvbw g[0] = gVal;
00199     }
00200   /* f, g, and df_dx are already in the right form. 
00201    * We need to fill in the multivectors df_dp, dg_dp, and dg_dx */
00202   
00203   /* if requested, copy the vectors df_dp into the columns of df_dp_mv */
00204   if (df_dp_mv.get() != 0)
00205     {
00206       Tabs tab2;
00207       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tab2 << "df_dp multivector was requested");
00208       for (int i=0; i<df_dp.size(); i++)
00209         {
00210           Vector<double> col = df_dp_mv->col(i);
00211           col.acceptCopyOf(df_dp[i]);
00212         }
00213     }
00214   else
00215     {
00216       Tabs tab2;
00217       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tab2 << "df_dp multivector was NOT requested");
00218     }
00219 
00220   /* 
00221    * If requested, set the dg_dx return value 
00222    */
00223   if (dg_dx_trans_mv.get() != 0)
00224     {
00225       Tabs tab2;
00226       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tab2 << "dg_dx multivector was requested");
00227       Vector<double> dg_dx_mv_row =  dg_dx_trans_mv->col(0);
00228       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_HIGH(tab2 << "extracted zeroth column: " 
00229                          << dg_dx_mv_row.description());
00230       TEST_FOR_EXCEPT(dg_dx_T.ptr().get()==0);
00231       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tab2 << "output from internal eval: " 
00232                            << dg_dx_T.description());
00233       dg_dx_mv_row.acceptCopyOf(dg_dx_T);
00234       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tab2 << "got dg_dx multivector");
00235     }
00236   else
00237     {
00238       Tabs tab2;
00239       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tab2 << "dg_dx multivector was NOT requested");
00240     }
00241 
00242   /* 
00243    * If requested, set the dg_dp return value 
00244    */
00245   if (dg_dp_trans_mv.get() != 0)
00246     {
00247       Tabs tab2;
00248       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tab2 << "dg_dp multivector was requested");
00249       Vector<double> dg_dp_mv_row =  dg_dp_trans_mv->col(0);
00250       dg_dp_mv_row.acceptCopyOf(dg_dp_T);
00251       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tab2 << "got dg_dp multivector");
00252 
00253     }
00254   else
00255     {
00256       Tabs tab2;
00257       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tab2 << "dg_dp multivector was NOT requested");
00258     }
00259 
00260   if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tabs << "done evaluation!");
00261 }
00262 
00263 
00264 
00265 #endif
00266 

Site Contact