SundanceNLOp.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 #include "SundanceNLOp.hpp"
00032 #include "SundanceOut.hpp"
00033 #include "SundanceTabs.hpp"
00034 #include "SundanceAssembler.hpp"
00035 #include "SundanceDiscreteFunction.hpp"
00036 #include "SundanceEquationSet.hpp"
00037 #include "SundanceLinearSolveDriver.hpp"
00038 #include "TSFLinearSolverDecl.hpp"
00039 
00040 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00041 #include "TSFLinearOperatorImpl.hpp"
00042 #include "TSFLinearSolverImpl.hpp"
00043 #include "TSFLinearCombinationImpl.hpp"
00044 #endif
00045 
00046 using namespace Sundance;
00047 using namespace Sundance;
00048 using namespace Sundance;
00049 using namespace Sundance;
00050 using namespace Sundance;
00051 using namespace Sundance;
00052 using namespace Sundance;
00053 using namespace Teuchos;
00054 using namespace std;
00055 using namespace TSFExtended;
00056 
00057 
00058 static Time& nlpCtorTimer() 
00059 {
00060   static RCP<Time> rtn 
00061     = TimeMonitor::getNewTimer("NLOp ctor"); 
00062   return *rtn;
00063 }
00064 
00065 
00066 NLOp::NLOp() 
00067   : NonlinearOperatorBase<double>(),
00068     assembler_(),
00069     u0_(),
00070     discreteU0_(0)
00071 {
00072   TimeMonitor timer(nlpCtorTimer());
00073 }
00074 
00075 
00076 NLOp::NLOp(const Mesh& mesh, 
00077   const Expr& eqn, 
00078   const Expr& bc,
00079   const Expr& test, 
00080   const Expr& unk, 
00081   const Expr& u0, 
00082   const VectorType<double>& vecType,
00083   bool partitionBCs)
00084   : NonlinearOperatorBase<double>(),
00085     assembler_(),
00086     u0_(u0),
00087     params_(),
00088     discreteU0_(0)
00089     
00090 {
00091   TimeMonitor timer(nlpCtorTimer());
00092 
00093   Expr unkParams;
00094   Expr fixedParams;
00095   Expr fixedFields;
00096   Expr unkParamValues;
00097   Expr fixedParamValues;
00098   Expr fixedFieldValues;
00099 
00100   RCP<EquationSet> eqnSet 
00101     = rcp(new EquationSet(eqn, bc, tuple(test.flattenSpectral()), tuple(unk.flattenSpectral()), tuple(u0),
00102         unkParams, unkParamValues,
00103         fixedParams, fixedParamValues,
00104         tuple(fixedFields), tuple(fixedFieldValues)));
00105 
00106   assembler_ = rcp(new Assembler(mesh, eqnSet, tuple(vecType), tuple(vecType), partitionBCs));
00107 
00108   discreteU0_ = dynamic_cast<DiscreteFunction*>(u0_.ptr().get());
00109 
00110   TEST_FOR_EXCEPTION(discreteU0_==0, RuntimeError,
00111     "null discrete function pointer in "
00112     "NLOp ctor");
00113 
00114   VectorSpace<double> domain = assembler_->solnVecSpace();
00115   VectorSpace<double> range = assembler_->rowVecSpace();
00116 
00117   setDomainAndRange(domain, range);
00118 }
00119 
00120 NLOp::NLOp(const Mesh& mesh, 
00121   const Expr& eqn, 
00122   const Expr& bc,
00123   const Expr& test, 
00124   const Expr& unk, 
00125   const Expr& u0, 
00126   const Expr& params, 
00127   const Expr& paramValues,  
00128   const VectorType<double>& vecType,
00129   bool partitionBCs)
00130   : NonlinearOperatorBase<double>(),
00131     assembler_(),
00132     J_(),
00133     u0_(u0),
00134     params_(params),
00135     discreteU0_(0)
00136     
00137 {
00138   TimeMonitor timer(nlpCtorTimer());
00139 
00140   Expr unkParams;
00141   Expr fixedFields;
00142   Expr unkParamValues;
00143   Expr fixedFieldValues;
00144 
00145   RCP<EquationSet> eqnSet 
00146     = rcp(new EquationSet(
00147             eqn, bc, tuple(test.flattenSpectral()), 
00148             tuple(unk.flattenSpectral()), tuple(u0), 
00149             unkParams, unkParamValues,
00150             params, paramValues,
00151             tuple(fixedFields), tuple(fixedFieldValues)));
00152 
00153   assembler_ = rcp(new Assembler(mesh, eqnSet, tuple(vecType), tuple(vecType), partitionBCs));
00154 
00155   discreteU0_ = dynamic_cast<DiscreteFunction*>(u0_.ptr().get());
00156 
00157   TEST_FOR_EXCEPTION(discreteU0_==0, RuntimeError,
00158     "null discrete function pointer in "
00159     "NLOp ctor");
00160 
00161   VectorSpace<double> domain = assembler_->solnVecSpace();
00162   VectorSpace<double> range = assembler_->rowVecSpace();
00163 
00164   setDomainAndRange(domain, range);
00165 }
00166 
00167 
00168 NLOp::NLOp(const RCP<Assembler>& assembler, 
00169   const Expr& u0)
00170   : NonlinearOperatorBase<double>(),
00171     assembler_(assembler),
00172     J_(),
00173     u0_(u0),
00174     params_(),
00175     discreteU0_(0)
00176 {
00177   TimeMonitor timer(nlpCtorTimer());
00178   discreteU0_ = dynamic_cast<DiscreteFunction*>(u0_.ptr().get());
00179 
00180   TEST_FOR_EXCEPTION(discreteU0_==0, RuntimeError,
00181     "null discrete function pointer in "
00182     "NLOp ctor");
00183 
00184   VectorSpace<double> domain = assembler_->solnVecSpace();
00185   VectorSpace<double> range = assembler_->rowVecSpace();
00186 
00187   setDomainAndRange(domain, range);
00188 }
00189 
00190 TSFExtended::Vector<double> NLOp::getInitialGuess() const 
00191 {
00192   TEST_FOR_EXCEPTION(discreteU0_==0, RuntimeError,
00193     "null discrete function pointer in "
00194     "NLOp::getInitialGuess()");
00195   
00196   Vector<double> u0 = discreteU0_->getVector();
00197 
00198   return u0;
00199 }
00200 
00201 void NLOp::setInitialGuess(const Expr& u0New) 
00202 {
00203   const DiscreteFunction* in = DiscreteFunction::discFunc(u0New);
00204   TEST_FOR_EXCEPT(in==0);
00205   setEvalPt(in->getVector().copy());
00206   discreteU0_->setVector(currentEvalPt());
00207 }
00208 
00209 
00210 LinearOperator<double> NLOp::allocateJacobian() const
00211 {
00212   return assembler_->allocateMatrix();
00213 }
00214 
00215 
00216 LinearOperator<double> NLOp::
00217 computeJacobianAndFunction(Vector<double>& functionValue) const
00218 {
00219   /* Set the vector underlying the discrete 
00220    * function to the evaluation point*/
00221 
00222   TEST_FOR_EXCEPTION(discreteU0_==0, RuntimeError,
00223     "null discrete function pointer in "
00224     "NLOp::jacobian()");
00225 
00226   TEST_FOR_EXCEPTION(currentEvalPt().ptr().get()==0, RuntimeError,
00227     "null evaluation point in "
00228     "NLOp::jacobian()");
00229 
00230   discreteU0_->setVector(currentEvalPt());
00231 
00232   Array<Vector<double> > mv(1);
00233   mv[0].acceptCopyOf(functionValue);
00234   assembler_->assemble(J_, mv);
00235   functionValue.acceptCopyOf(mv[0]);
00236 
00237   return J_;
00238 }
00239 
00240 void NLOp::
00241 computeJacobianAndFunction(LinearOperator<double>& J,
00242   Vector<double>& resid) const
00243 {
00244   /* Set the vector underlying the discrete 
00245    * function to the evaluation point*/
00246 
00247   TEST_FOR_EXCEPTION(discreteU0_==0, RuntimeError,
00248     "null discrete function pointer in "
00249     "NLOp::jacobian()");
00250 
00251   TEST_FOR_EXCEPTION(currentEvalPt().ptr().get()==0, RuntimeError,
00252     "null evaluation point in "
00253     "NLOp::jacobian()");
00254 
00255   TEST_FOR_EXCEPTION(J.ptr().get()==0, RuntimeError,
00256     "null Jacobian pointer in "
00257     "NLOp::jacobian()");
00258 
00259   TEST_FOR_EXCEPTION(resid.ptr().get()==0, RuntimeError,
00260     "null residual pointer in "
00261     "NLOp::jacobian()");
00262 
00263   discreteU0_->setVector(currentEvalPt());
00264 
00265   Array<Vector<double> > mv(1);
00266   mv[0] = resid;
00267 
00268   assembler_->assemble(J, mv);
00269 
00270   resid.acceptCopyOf(mv[0]);
00271 
00272   J_ = J;
00273 }
00274 
00275 
00276 
00277 
00278 Vector<double> NLOp::computeFunctionValue() const 
00279 {
00280   /* Set the vector underlying the discrete 
00281    * function to the evaluation point*/
00282 
00283   TEST_FOR_EXCEPTION(discreteU0_==0, RuntimeError,
00284     "null discrete function pointer in "
00285     "NLOp::computeFunctionValue()");
00286 
00287   TEST_FOR_EXCEPTION(currentEvalPt().ptr().get()==0, RuntimeError,
00288     "null evaluation point in "
00289     "NLOp::computeFunctionValue()");
00290 
00291   discreteU0_->setVector(currentEvalPt());
00292 
00293   Vector<double> rtn = createMember(range());
00294 
00295   Array<Vector<double> > mv(1);
00296   mv[0] = rtn;
00297 
00298   assembler_->assemble(mv);
00299 
00300   rtn.acceptCopyOf(mv[0]);
00301 
00302   return rtn;
00303 }
00304 
00305 
00306 
00307 void NLOp::computeFunctionValue(Vector<double>& resid) const 
00308 {
00309   /* Set the vector underlying the discrete 
00310    * function to the evaluation point*/
00311 
00312   TEST_FOR_EXCEPTION(discreteU0_==0, RuntimeError,
00313     "null discrete function pointer in "
00314     "NLOp::computeFunctionValue()");
00315 
00316   TEST_FOR_EXCEPTION(currentEvalPt().ptr().get()==0, RuntimeError,
00317     "null evaluation point in "
00318     "NLOp::computeFunctionValue()");
00319 
00320   TEST_FOR_EXCEPTION(resid.ptr().get()==0, RuntimeError,
00321     "null residual pointer in "
00322     "NLOp::computeFunctionValue()");
00323 
00324   discreteU0_->setVector(currentEvalPt());
00325 
00326 
00327   Array<Vector<double> > mv(1);
00328   mv[0] = resid;
00329 
00330   assembler_->assemble(mv);
00331 
00332   resid.acceptCopyOf(mv[0]);
00333 }
00334 
00335 
00336 
00337 Expr NLOp::
00338 computeSensitivities(const LinearSolver<double>& solver) const
00339 {
00340   /* Set the vector underlying the discrete 
00341    * function to the evaluation point*/
00342 
00343   TEST_FOR_EXCEPTION(discreteU0_==0, RuntimeError,
00344     "null discrete function pointer in "
00345     "NLOp::computeSensitivities()");
00346 
00347   TEST_FOR_EXCEPTION(currentEvalPt().ptr().get()==0, RuntimeError,
00348     "null evaluation point in "
00349     "NLOp::computeSensitivities()");
00350 
00351   TEST_FOR_EXCEPTION(J_.ptr().get()==0, RuntimeError,
00352     "null Jacobian pointer in "
00353     "NLOp::computeSensitivities()");
00354 
00355   TEST_FOR_EXCEPTION(params_.ptr().get()==0, RuntimeError,
00356     "null parameters in NLOp::computeSensitivities()");
00357 
00358 
00359   discreteU0_->setVector(currentEvalPt());
00360 
00361   Array<Vector<double> > mv(params_.size());
00362 
00363   assembler_->assembleSensitivities(J_, mv);
00364 
00365   LinearSolveDriver driver;
00366 
00367   Expr sens;
00368   int vrb = 0;
00369   Array<Array<string> > names(params_.size());
00370   for (int i=0; i<params_.size(); i++)
00371   {
00372     names[i].resize(u0_.size());
00373     for (int j=0; j<u0_.size(); j++) 
00374       names[i][j]="sens(" + u0_[j].toString() + ", " + params_[i].toString() + ")";
00375     mv[i].scale(-1.0);
00376   }
00377 
00378   driver.solve(solver, J_, mv, assembler_->solutionSpace(), names, vrb, sens);
00379   return sens;
00380 }

Site Contact