Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
00098 for (int i=0; i<initParams_.size(); i++)
00099 {
00100 tempinitParams = initParams_[i];
00101 Thyra::set_ele(i, tempinitParams, rtn.ptr().get());
00102
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
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
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
00145
00146 if (MPIComm::world().getRank()==0) SUNDANCE_VERB_HIGH(tabs << "state vector is "
00147 << stateVec.description());
00148 prob_.setEvalPt(stateVec);
00149
00150
00151
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
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
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
00203
00204
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
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
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
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
00287 solver.solve();
00288 }
00289
00290
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