PlayaNonlinearOperatorBase.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                 Playa: Programmable Linear Algebra
00005 //                 Copyright 2012 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 #ifndef PLAYA_NONLINEAROPERATORBASE_HPP
00043 #define PLAYA_NONLINEAROPERATORBASE_HPP
00044 
00045 #include "PlayaDefs.hpp"
00046 #include "PlayaHandleable.hpp"
00047 #include "PlayaOut.hpp"
00048 #include "PlayaObjectWithVerbosity.hpp"
00049 #include "PlayaVectorDecl.hpp"
00050 #include "PlayaLinearOperatorDecl.hpp"
00051 #include "PlayaLinearCombinationDecl.hpp"
00052 
00053 namespace Playa
00054 {
00055 using namespace Teuchos;
00056 
00057 /** 
00058  * Base class for nonlinear operators
00059  */
00060 template <class Scalar>
00061 class NonlinearOperatorBase 
00062   : public Handleable<NonlinearOperatorBase<Scalar> >,
00063     public ObjectWithVerbosity
00064 {
00065 public:
00066   /** Empty ctor, for contexts in which we don't know the
00067    * domain and range spaces at the beginning of construction time */
00068   NonlinearOperatorBase() 
00069     : domain_(), range_(), 
00070       jacobianIsValid_(false),
00071       residualIsValid_(false),
00072       currentEvalPt_(),
00073       currentFunctionValue_(),
00074       currentJ_()
00075     {;}
00076 
00077   /** Construct a nonlinear operator with a domain and range */
00078   NonlinearOperatorBase(const VectorSpace<Scalar>& domain,
00079     const VectorSpace<Scalar>& range) 
00080     : domain_(domain.ptr()), range_(range.ptr()), 
00081       jacobianIsValid_(false),
00082       residualIsValid_(false),
00083       currentEvalPt_(),
00084       currentFunctionValue_(),
00085       currentJ_()
00086     {;}
00087                             
00088   /** Return the domain space */
00089   const RCP<const VectorSpaceBase<Scalar> >& domain() const 
00090     {return domain_;}
00091 
00092   /** Return the range space */
00093   const RCP<const VectorSpaceBase<Scalar> >& range() const 
00094     {return range_;}
00095 
00096   /** Set the evaluation point */
00097   void setEvalPt(const Vector<Scalar>& x) const 
00098     {
00099       if (this->verb() >= 1)
00100       {
00101         Out::os() << "NonlinearOperatorBase Setting new eval pt";
00102         if (this->verb() > 3)
00103         {
00104           Out::os() << " to " << std::endl ;
00105           x.print(Out::os());
00106         }
00107         Out::os() << std::endl;
00108       }
00109       jacobianIsValid_ = false;
00110       residualIsValid_ = false;
00111 
00112       currentEvalPt_.acceptCopyOf(x);
00113     }
00114 
00115   /** Get the current point at which the function is to be 
00116    * evaluated */
00117   const Vector<double>& currentEvalPt() const {return currentEvalPt_;}
00118 
00119   /** Return the Jacobian at the current evaluation point */
00120   LinearOperator<double> getJacobian() const 
00121     {
00122       if (this->verb() > 1)
00123       {
00124         Out::os() << "NonlinearOperatorBase getting Jacobian" << std::endl;
00125       }
00126       if (!jacobianIsValid_)
00127       {
00128         if (this->verb() > 3)
00129         {
00130           Out::os() << "...computing new J and F" << std::endl;
00131         }
00132         currentJ_ 
00133           = computeJacobianAndFunction(currentFunctionValue_);
00134         jacobianIsValid_ = true;
00135         residualIsValid_ = true;
00136       }
00137       else
00138       {
00139         if (this->verb() > 1)
00140         {
00141           Out::os() << "...reusing valid J" << std::endl;
00142         }
00143       }
00144       if (this->verb() > 3)
00145       {
00146         Out::os() << "J is " << std::endl;
00147         currentJ_.print(Out::os());
00148         Out::os() << std::endl;
00149       }
00150       return currentJ_;
00151     }
00152 
00153       
00154 
00155   /** Return the function value at the current evaluation point */
00156   Vector<double> getFunctionValue() const 
00157     {
00158       if (this->verb() > 1)
00159       {
00160         Out::os() << "NonlinearOperatorBase getting function value" << std::endl;
00161       }
00162       if (!residualIsValid_)
00163       {
00164         if (this->verb() > 1)
00165         {
00166           Out::os() << "...computing new F" << std::endl;
00167         }
00168         currentFunctionValue_ = computeFunctionValue();
00169         residualIsValid_ = true;
00170       }
00171       else
00172       {
00173         if (this->verb() > 1)
00174         {
00175           Out::os() << "...reusing valid F" << std::endl;
00176         }
00177       }
00178 
00179       if (this->verb() > 3)
00180       {
00181         Out::os() << "F is " << std::endl;
00182         currentFunctionValue_.print(Out::os());
00183         Out::os() << std::endl;
00184       }
00185       return currentFunctionValue_;
00186     }
00187 
00188 
00189   /** Return an initial guess appropriate to this problem */
00190   virtual Vector<double> getInitialGuess() const = 0 ;
00191 
00192 
00193 protected:
00194 
00195   /** Compute the Jacobian at the current eval point */
00196   virtual LinearOperator<Scalar> computeJacobianAndFunction(Vector<double>& functionValue) const = 0 ;
00197 
00198   /** Compute the function value at the current eval point */
00199   virtual Vector<Scalar> computeFunctionValue() const 
00200     {
00201       computeJacobianAndFunction(currentFunctionValue_);
00202       return currentFunctionValue_;
00203     }
00204 
00205       
00206   /** Set the domain and range. This is protected so that solver
00207    * developers don't try to change the spaces on the fly */
00208   void setDomainAndRange(const VectorSpace<Scalar>& domain,
00209     const VectorSpace<Scalar>& range)
00210     {
00211       domain_ = domain.ptr();
00212       range_ = range.ptr();
00213     }
00214 
00215 
00216 private:
00217   /** */
00218   RCP<const VectorSpaceBase<Scalar> > domain_;
00219 
00220   /** */
00221   RCP<const VectorSpaceBase<Scalar> > range_;
00222 
00223   /** */
00224   mutable bool jacobianIsValid_;
00225 
00226   /** */
00227   mutable bool residualIsValid_;
00228 
00229   /** */
00230   mutable Vector<double> currentEvalPt_;
00231 
00232   /** */
00233   mutable Vector<double> currentFunctionValue_;
00234 
00235   /** */
00236   mutable LinearOperator<double> currentJ_;
00237 };
00238 
00239 
00240 
00241  
00242 }
00243 
00244 
00245 #endif

Site Contact