SundanceNLPModelEvaluator.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 "TSFNOXSolver.H"
00037 #include "SundanceNLPModelEvaluator.hpp"
00038 
00039 
00040 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00041 #include "TSFVectorImpl.hpp"
00042 #endif
00043 
00044 #ifdef HAVE_SUNDANCE_MOOCHO 
00045 #ifdef BROKEN
00046 
00047 SundanceNLPModelEvaluator::SundanceNLPModelEvaluator(const VectorType<double>& vecType)
00048   : SundanceModelEvaluator(vecType),
00049     paramSpace_(),
00050     initParams_(),
00051     paramExpr_(),
00052     stateExpr_(),
00053     prob_(),
00054     sensProb_(),
00055     obj_(),
00056     objEval_(),
00057     contParams_(),
00058     finalContParams_()
00059 {;}
00060 
00061 
00062 void SundanceNLPModelEvaluator::initialize(const Expr& paramExpr,
00063                                            const Expr& stateExpr,
00064                                            const Expr& stateExprVal,
00065                                            const NonlinearProblem& prob, 
00066                                            const Array<LinearProblem>& sensProb,
00067                                            const Functional& objective)
00068 {
00069   paramExpr_ = paramExpr.flatten();
00070   stateExpr_ = stateExprVal;
00071   prob_ = prob;
00072   sensProb_ = sensProb;
00073   obj_ = objective;
00074   objEval_ = obj_.evaluator(stateExpr, stateExprVal);
00075   RCP<const Thyra::VectorSpaceBase<double> > pSpace
00076     = rcp(new Thyra::DefaultSpmdVectorSpace<double>(paramExpr_.size()));
00077   paramSpace_ = pSpace;
00078 }
00079 
00080 void SundanceNLPModelEvaluator::setInitialParameters(const Array<double>& a)
00081 {
00082   initParams_ = a;
00083 }
00084 
00085 
00086 Vector<double> SundanceNLPModelEvaluator::getInitialParameters() const 
00087 {
00088   Vector<double> rtn = paramSpace().createMember();
00089   if (initParams_.size() == 0)
00090     {
00091       rtn.setToConstant(0.0);
00092     }
00093   else
00094     {
00095       double tempinitParams;
00096       TEST_FOR_EXCEPT(initParams_.size() != rtn.space().dim());
00097       //      for (int i=0; i<initParams_.size(); i++)
00098       for (int i=0; i<initParams_.size(); i++)
00099         {
00100           tempinitParams = initParams_[i];
00101     Thyra::set_ele(i, tempinitParams, rtn.ptr().get()); 
00102     //bvbw    rtn[i] = initParams_[i];
00103         }
00104     }
00105   return rtn;
00106 }
00107 
00108 void SundanceNLPModelEvaluator::internalEvalModel(const Vector<double>& stateVec,
00109                                                   const Vector<double>& params,
00110                                                   Vector<double>& resid,
00111                                                   double& objFuncVal,
00112                                                   LinearOperator<double>& df_dx,
00113                                                   Array<Vector<double> >& df_dp,
00114                                                   Vector<double>& dg_dp_T,
00115                                                   Vector<double>& dg_dx_T) const 
00116 {
00117   Tabs tabs;
00118 
00119   TEST_FOR_EXCEPTION(params.ptr().get()==0, RuntimeError,
00120                      "null params vector!");
00121   TEST_FOR_EXCEPTION( (int) paramExpr_.size() != params.space().dim(),
00122                       RuntimeError,
00123                       "Mismatch between input parameter vector space and "
00124                       "symbolic parameter object size");
00125 
00126   TEST_FOR_EXCEPTION(stateVec.ptr().get()==0, RuntimeError,
00127                      "null state vector!");
00128 
00129 
00130   /* set the symbolic parameter values to the input parameters */
00131   if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tabs << "parameters are: ")
00132     {
00133       for (int i=0; i<paramExpr_.size(); i++)
00134   {
00135     Tabs tab2;
00136     Expr p_i = paramExpr_[i];
00137     //bvbw    p_i.setParameterValue(params[i]);
00138     p_i.setParameterValue(params.getElement(i));
00139     if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tab2 << i << " " << paramExpr_[i]);
00140   }
00141     }
00142   
00143 
00144   /* set the symbolic state function value to the input state */
00145 
00146   if (MPIComm::world().getRank()==0) SUNDANCE_VERB_HIGH(tabs << "state vector is " 
00147                        << stateVec.description());
00148   prob_.setEvalPt(stateVec);
00149   
00150 
00151   /* compute the Jacobian and residual of the constraints */
00152   if (df_dx.ptr().get()!=0 && resid.ptr().get() != 0)
00153     {
00154       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tabs << "computing Jacobian and residual...");
00155       prob_.computeJacobianAndFunction(df_dx, resid);          
00156       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_HIGH(tabs << "residual vector is " 
00157                          << resid.description());
00158     }
00159   else if (resid.ptr().get() != 0 && df_dx.ptr().get()==0)
00160     {
00161       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tabs << "computing residual w/o Jacobian...");
00162       prob_.computeFunctionValue(resid);         
00163       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_HIGH(tabs << "residual vector is " 
00164                          << resid.description());
00165     }
00166   else if (df_dx.ptr().get()!=0 && resid.ptr().get() == 0)
00167     {
00168       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tabs << "computing Jacobian w/o residual...");
00169       Vector<double> dummy = constraintSpace().createMember();
00170       prob_.computeJacobianAndFunction(df_dx, dummy);          
00171     }
00172   else
00173     {
00174       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tabs << "requested neither the residual "
00175                            "nor the Jacobian");
00176     }
00177         
00178 
00179   /* compute the derivatives of the constraint residual wrt the parameters */
00180   if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tabs << "computing sensitivities...");
00181   for (int i=0; i<paramExpr_.size(); i++)
00182     {
00183       df_dp[i] = sensProb_[i].getRHS();
00184     }
00185 
00186   /* evaluate the objective function and its gradient wrt the states */ 
00187   if (dg_dx_T.ptr().get() != 0)
00188     {
00189       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tabs << "computing objective function "
00190                            "and gradient");
00191       Expr df_dx_Expr = objEval_.evalGradient(objFuncVal);
00192       dg_dx_T.acceptCopyOf(DiscreteFunction::discFunc(df_dx_Expr)->getVector());
00193     }
00194   else
00195     {
00196       if (MPIComm::world().getRank()==0) SUNDANCE_VERB_MEDIUM(tabs << "computing objective function");
00197       objFuncVal = objEval_.evaluate();
00198     }
00199       
00200 
00201 
00202   /* evaluate the derivatives of the objective function wrt 
00203    * the parameters */
00204   /* set the symbolic parameter values to the input parameters */
00205   if (dg_dp_T.ptr().get() != 0)
00206     {
00207       dg_dp_T.setToConstant(0.0);
00208     }
00209 }
00210 
00211 
00212 Array<double> SundanceNLPModelEvaluator::parameters() const
00213 {
00214   Array<double> rtn;
00215   for (int i=0; i<paramExpr_.size(); i++)
00216     {
00217       const SpatiallyConstantExpr* sce 
00218         = dynamic_cast<const SpatiallyConstantExpr*>(paramExpr_[i].ptr().get());
00219       rtn.append(sce->value());
00220     }
00221   return rtn;
00222 }
00223 
00224 Array<double> SundanceNLPModelEvaluator
00225 ::paramArray(const ParameterList& params,
00226              const std::string& paramName) const
00227 {
00228   std::string str = getParameter<string>(params, paramName);
00229   Array<string> toks = StrUtils::stringTokenizer(str);
00230   Array<double> rtn(toks.size());
00231   for (int i=0; i<toks.size(); i++)
00232     {
00233       rtn[i] = StrUtils::atof(toks[i]);
00234     }
00235   return rtn;
00236 }
00237 
00238 
00239 Expr SundanceNLPModelEvaluator
00240 ::solveForward(const ParameterList& fwdParams) const
00241 {
00242 
00243   RCP<TSFExtended::NonlinearOperatorBase<double> > p 
00244     = rcp(&prob_, false);
00245   TSFExtended::NonlinearOperator<double> prob = p;
00246 
00247 
00248   /* set up the nonlinear solver */
00249   TEST_FOR_EXCEPT(!fwdParams.isSublist("Nonlinear Solver"));
00250 
00251   ParameterList nonlinParams = fwdParams.sublist("Nonlinear Solver");
00252   int numContSteps = 1;
00253   if (nonlinParams.isParameter("Number of Continuation Steps"))
00254     {
00255       numContSteps = getParameter<int>(nonlinParams, "Number of Continuation Steps");
00256     }
00257 
00258   TSFExtended::NOXSolver solver(nonlinParams, prob);
00259 
00260 
00261   /* set the design parameters as given in the the XML input */
00262   TEST_FOR_EXCEPT(!fwdParams.isParameter("Design Parameters"));
00263   Array<double> designParams = paramArray(fwdParams, "Design Parameters");
00264   TEST_FOR_EXCEPT(designParams.size() != paramExpr_.size());
00265                      
00266   for (int i=0; i<paramExpr_.size(); i++)
00267     {
00268       Tabs tab2;
00269       Expr p_i = paramExpr_[i];
00270       p_i.setParameterValue(designParams[i]);
00271       if (MPIComm::world().getRank()==0) 
00272         SUNDANCE_VERB_MEDIUM(tab2 << i << " " << paramExpr_[i]);
00273     }
00274 
00275   /* run the continuation loop */
00276   for (int i=0; i<numContSteps; i++)
00277     {
00278       for (int j=0; j<numContinuationParameters(); j++)
00279         {
00280           Expr c = continuationParameters(j);
00281           Expr cFinal = finalContinuationValues(j);
00282           double cStep = cFinal.getParameterValue() * ((double) i)/((double) numContSteps-1);
00283 
00284           c.setParameterValue(cStep);
00285         }
00286       /* solve, writing the solution into stateExpr_ */
00287       solver.solve();
00288     }
00289   
00290   /* copy the solution from stateExpr into a new field */
00291   const DiscreteSpace& discSpace 
00292     = DiscreteFunction::discFunc(stateExpr_)->discreteSpace();
00293   const Vector<double>& vec 
00294     = DiscreteFunction::discFunc(stateExpr_)->getVector().copy();
00295   
00296   return new DiscreteFunction(discSpace, vec);
00297   
00298   
00299 }
00300 
00301 #endif
00302 #endif
00303 

Site Contact