PDEOptPDEConstrainedObjBase.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
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     /* hold all the other variables fixed */
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   /* Solve for the state and adjoint variables */
00166   solveStateAndAdjoint(x);
00167 
00168   /* Compute the gradient using the adjoint method */
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   /* Solve for the state variables */
00185   solveState(x);
00186 
00187   /* Set all the adjoints to zero. We do this because the residual of the state
00188    * equation might not be exactly zero. This way, we can evaluate the Lagrangian
00189    * an have zero contribution from the constraint term. */
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   /* Evaluate the functional */
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 

Site Contact