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
00035
00036
00037
00038
00039
00040
00041
00042
00043 #include "PDEOptPDEConstrainedObjBase.hpp"
00044 #include "Sundance.hpp"
00045
00046
00047 using namespace Teuchos;
00048 using namespace Playa;
00049 using namespace Sundance;
00050
00051 using std::endl;
00052 using std::runtime_error;
00053
00054
00055 PDEConstrainedObjBase::PDEConstrainedObjBase(
00056 const Functional& lagrangian,
00057 const Array<Expr>& stateVarVals,
00058 const Array<Expr>& adjointVarVals,
00059 const Expr& designVarVal,
00060 int verb)
00061 : ObjectiveBase(verb),
00062 Lagrangian_(lagrangian),
00063 designVarVal_(designVarVal),
00064 stateVarVals_(stateVarVals),
00065 adjointVarVals_(adjointVarVals),
00066 fEval_(),
00067 numFuncEvals_(0),
00068 numGradEvals_(0),
00069 invHScale_(1.0),
00070 iterCallback_()
00071 {}
00072
00073
00074 PDEConstrainedObjBase::PDEConstrainedObjBase(
00075 const Functional& lagrangian,
00076 const Array<Expr>& stateVarVals,
00077 const Array<Expr>& adjointVarVals,
00078 const Expr& designVarVal,
00079 const RCP<IterCallbackBase>& iterCallback,
00080 int verb)
00081 : ObjectiveBase(verb),
00082 Lagrangian_(lagrangian),
00083 designVarVal_(designVarVal),
00084 stateVarVals_(stateVarVals),
00085 adjointVarVals_(adjointVarVals),
00086 fEval_(),
00087 numFuncEvals_(0),
00088 numGradEvals_(0),
00089 invHScale_(1.0),
00090 iterCallback_(iterCallback)
00091 {}
00092
00093
00094 void PDEConstrainedObjBase::init(
00095 const Array<Expr>& stateVars,
00096 const Array<Expr>& adjointVars,
00097 const Expr& designVar)
00098 {
00099 TEUCHOS_TEST_FOR_EXCEPTION(stateVars.size() != adjointVars.size(),
00100 RuntimeError,
00101 "number of state and adjoint variables should be identical");
00102
00103 TEUCHOS_TEST_FOR_EXCEPTION(stateVars.size() != stateVarVals_.size(),
00104 RuntimeError,
00105 "number of state variables and state values "
00106 "should be identical");
00107
00108 TEUCHOS_TEST_FOR_EXCEPTION(adjointVars.size() != adjointVarVals_.size(),
00109 RuntimeError,
00110 "number of adjoint variables and adjoint values "
00111 "should be identical");
00112
00113 Array<Array<Expr> > fixedVarsInStateEqns(stateVars.size());
00114 Array<Array<Expr> > fixedVarsInStateEqnsVals(stateVars.size());
00115
00116 Array<Array<Expr> > fixedVarsInAdjointEqns(stateVars.size());
00117 Array<Array<Expr> > fixedVarsInAdjointEqnsVals(stateVars.size());
00118
00119 for (int i=0; i<stateVars.size(); i++)
00120 {
00121
00122 fixedVarsInStateEqns[i].append(designVar);
00123 fixedVarsInStateEqnsVals[i].append(designVarVal_);
00124 for (int j=0; j<stateVars.size(); j++)
00125 {
00126 if (i != j)
00127 {
00128 fixedVarsInStateEqns[i].append(stateVars[j]);
00129 fixedVarsInStateEqnsVals[i].append(stateVarVals_[j]);
00130 fixedVarsInAdjointEqns[i].append(adjointVars[j]);
00131 fixedVarsInAdjointEqnsVals[i].append(adjointVarVals_[j]);
00132 fixedVarsInStateEqns[i].append(adjointVars[j]);
00133 fixedVarsInStateEqnsVals[i].append(adjointVarVals_[j]);
00134 fixedVarsInAdjointEqns[i].append(stateVars[j]);
00135 fixedVarsInAdjointEqnsVals[i].append(stateVarVals_[j]);
00136 }
00137 }
00138 }
00139
00140 initEquations(stateVars, adjointVars,
00141 fixedVarsInStateEqns, fixedVarsInStateEqnsVals,
00142 fixedVarsInAdjointEqns, fixedVarsInAdjointEqnsVals);
00143
00144 Array<Expr> allVarArray = stateVars;
00145 Array<Expr> allVarValArray = stateVarVals_;
00146 for (int i=0; i<adjointVars.size(); i++)
00147 {
00148 allVarArray.append(adjointVars[i]);
00149 allVarValArray.append(adjointVarVals_[i]);
00150 }
00151 Expr allVars = new ListExpr(allVarArray);
00152 Expr allVarVals = new ListExpr(allVarValArray);
00153
00154 fEval_ = Lagrangian_.evaluator(designVar, designVarVal_,
00155 allVars, allVarVals);
00156 }
00157
00158
00159 void PDEConstrainedObjBase::evalGrad(const Vector<double>& x, double& f,
00160 Vector<double>& grad) const
00161 {
00162 Tabs tabs(0);
00163 PLAYA_MSG2(verb(), tabs << "in evalGrad()");
00164
00165
00166 solveStateAndAdjoint(x);
00167
00168
00169 Expr gradExpr = fEval_.evalGradient(f);
00170 grad = getDiscreteFunctionVector(gradExpr).copy();
00171
00172 PLAYA_MSG2(verb(), tabs << "function value = " << f);
00173 PLAYA_MSG5(verb(), tabs << "|gradient| is " << grad.norm2());
00174 PLAYA_MSG5(verb(), tabs << "gradient is " << grad);
00175 numFuncEvals_++;
00176 numGradEvals_++;
00177 }
00178
00179 void PDEConstrainedObjBase::eval(const Vector<double>& x, double& f) const
00180 {
00181 Tabs tabs(0);
00182 PLAYA_MSG2(verb(), tabs << "in eval()");
00183
00184
00185 solveState(x);
00186
00187
00188
00189
00190 for (int i=0; i<adjointVarVals_.size(); i++)
00191 {
00192
00193 Vector<double> adjVec = getDiscreteFunctionVector(adjointVarVals_[i]);
00194 adjVec.zero();
00195 setDiscreteFunctionVector(adjointVarVals_[i], adjVec);
00196 }
00197
00198
00199 f = fEval_.evaluate();
00200 PLAYA_MSG2(verb(), tabs << "function value = " << f);
00201 numFuncEvals_++;
00202 }
00203
00204
00205 Vector<double> PDEConstrainedObjBase::getInit() const
00206 {
00207 return getDiscreteFunctionVector(designVarVal());
00208 }
00209
00210 void PDEConstrainedObjBase:: iterationCallback(const Vector<double>& x,
00211 int iter) const
00212 {
00213 if (iterCallback_.ptr().get() != 0)
00214 {
00215 iterCallback_->call(this, iter);
00216 }
00217 }
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228