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

Site Contact