SundanceDeriv.hpp
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 #ifndef SUNDANCE_DERIV_H
00043 #define SUNDANCE_DERIV_H
00044 
00045 #include "SundanceDefs.hpp"
00046 #include "SundanceSpatialDerivSpecifier.hpp"
00047 #include "SundanceFunctionIdentifier.hpp"
00048 #include "Teuchos_RefCountPtr.hpp"
00049 
00050 namespace Sundance
00051 {
00052 using namespace Sundance;
00053 using namespace Teuchos;
00054 class SymbolicFunc;
00055 class Parameter;
00056 class SymbolicFuncElement;
00057 class SymbolicFuncDescriptor;
00058 class CommonFuncDataStub;
00059 
00060 enum DerivType {CoordDT, FunctionalDT, NullDT};
00061 
00062 /**
00063  * The purpose of this class is to represent first-order 
00064  * spatial or functional differential operators. This object 
00065  * should not be confused with the user-level Derivative
00066  * object, which represents spatial differential operators as appearing
00067  * in a user-level problem specification.
00068  *
00069  * <h4> Functional vs spatial derivatives </h4>
00070  *
00071  * The bridge theorem involves expressions of the form
00072  * \f[
00073  * \frac{\partial \mathcal{F}}{\partial L(u)} L(\phi_u)
00074  * \f]
00075  * and
00076  * \f[
00077  * \frac{\partial^2 \mathcal{F}}{\partial L(u)\partial M(v)} 
00078  * L(\phi_u)M(\psi_v)
00079  * \f]
00080  * where \f$L(u)\f$ is some spatial differential operator acting on the
00081  * function \f$u\f$, and \f$\phi_u\f$ is a basis function with which
00082  * \f$u\f$ is represented.
00083  * A derivative such as \f$\frac{\partial \mathcal{F}}{\partial L(u)}\f$ will
00084  * be called a functional derivative to distinguish it from derivatives
00085  * with respect to spatial coordinates, such as 
00086  * \f$\frac{\partial \mathcal{F}}{\partial x}\f$.
00087  * The following table shows the types of derivative currently supported.
00088  * <table>
00089  * <tr> 
00090  * <td>Operation</td>
00091  * <td>Geometry of derivative value</td> 
00092  * <td>Operating function geometry</td> 
00093  * <td>Operating spatial operator</td>
00094  * <td>Operating function subtype</td>
00095  * </tr>
00096  * <tr> 
00097  * <td>\f$ \frac{\partial}{\partial x}\f$ </td>
00098  * <td> Scalar </td>
00099  * <td> Coordinate component </td> 
00100  * <td> N/A </td>
00101  * <td> N/A </td> 
00102  * </tr>
00103  * <tr> 
00104  * <td>\f$ \frac{\partial}{\partial p}\f$ </td>
00105  * <td> Scalar </td>
00106  * <td> Scalar (\f$L^2\f$)</td> 
00107  * <td> Identity </td>
00108  * <td> SymbolicFuncElement </td> 
00109  * </tr>
00110  * <tr> 
00111  * <td>\f$ \frac{\partial}{\partial D_\alpha p}\f$ </td>
00112  * <td> Coordinate component </td>
00113  * <td> Scalar (\f$H^1\f$)</td> 
00114  * <td> Partial derivative \f$D_\alpha\f$ </td>
00115  * <td> SymbolicFuncElement </td> 
00116  * </tr>
00117  * <tr> 
00118  * <td>\f$ \frac{\partial}{\partial D_n p}\f$ </td>
00119  * <td> Normal component </td>
00120  * <td> Scalar (\f$H^1\f$) </td> 
00121  * <td> Normal derivative \f${\bf n}\cdot \nabla\f$ </td>
00122  * <td> SymbolicFuncElement </td> 
00123  * </tr>
00124  * <tr> 
00125  * <td>\f$ \frac{\partial}{\partial \mathrm{div}({\bf u})}\f$ </td>
00126  * <td> Scalar </td>
00127  * <td> Vector (\f${\bf H}(div)\f$)</td>
00128  * <td> Divergence </td> 
00129  * <td> SymbolicFunc </td> 
00130  * </tr>
00131  * <tr> 
00132  * <td>\f$ \frac{\partial}{\partial {\bf u\cdot e_\alpha}}\f$ </td>
00133  * <td> Coordinate component </td>
00134  * <td> Vector (\f${\bf H}^1\f$, \f${\bf H}(div)\f$, or \f${\bf H}(curl)\f$)</td> 
00135  * <td> Inner product with coordinate unit vector </td> 
00136  * <td> SymbolicFuncElement </td> 
00137  * </tr>
00138  * <tr> 
00139  * <td>\f$ \frac{\partial}{\partial {\bf u\cdot n}}\f$ </td>
00140  * <td> Normal component </td>
00141  * <td> Vector (\f${\bf H}^1\f$ or \f${\bf H}(div)\f$)</td> 
00142  * <td> Inner product with normal unit vector </td> 
00143  * <td> SymbolicFunc </td> 
00144  * </tr>
00145  * <tr> 
00146  * <td>\f$ \frac{\partial}{\partial D_\alpha ({\bf u\cdot e_\beta})}\f$ </td>
00147  * <td> Coordinate component </td>
00148  * <td> Vector (\f${\bf H}^1\f$) </td> 
00149  * <td> Inner product with normal unit vector </td> 
00150  * <td> SymbolicFuncElement </td> 
00151  * </tr>
00152  * </table>
00153  */
00154 class Deriv : public EnumTypeField<DerivType>
00155 {
00156 public:
00157   /** An empty ctor is needed for use with std::vector. The empty
00158    * ctor creates a null derivative, representing an identity operator.*/
00159   Deriv();
00160 
00161   /** Construct a deriv wrt a coordinate, e.g., \f$D_x\f$. */
00162   Deriv(int coordDir);
00163 
00164   /** Construct a deriv wrt an object of length one, for example,
00165    * a scalar function or a single component of a vector function, or
00166    * possibly a spatial derivative of such an object. 
00167    * Examples: 
00168    * <ul>
00169    * <li> \f$T\f$ is a scalar-valued function
00170    * */
00171   Deriv(
00172     const SymbolicFuncElement* func,
00173     const SpatialDerivSpecifier& d
00174   );
00175 
00176   /** Construct a deriv wrt a function */
00177   Deriv( 
00178     const SymbolicFunc* func,
00179     const SpatialDerivSpecifier& d
00180     );
00181 
00182 
00183   /** Comparison operator for use in sets and maps */
00184   bool operator<(const Deriv& other) const ;
00185 
00186   /** Equality test operator */
00187   bool operator==(const Deriv& other) const ;
00188 
00189   /** Write to a std::string
00190    * \param verbose If true, write all details for the object. If false, 
00191    * write a simple description giving only the function name and the
00192    * specification of a derivative.
00193    */
00194   std::string toString(bool verbose=false) const ;
00195 
00196   /** True if this is a derivative wrt a spatial coordinate */
00197   bool isCoordDeriv() const {return type()==CoordDT;}
00198 
00199   /** True if this is a derivative wrt a function 
00200    * or a spatial derivative of a function */
00201   bool isFunctionalDeriv() const {return type()==FunctionalDT;}
00202 
00203   /** True if my operative function is a test function */
00204   bool isTestFunction() const ;
00205 
00206   /** True if my operative function is unknown */
00207   bool isUnknownFunction() const ;
00208 
00209   /** True if my operative function is a parameter */
00210   bool isParameter() const ;
00211 
00212   /** Create a new functional derivative in which the function
00213    * has been differentiated spatially by the given multi index, for example,
00214    * <tt>derivWrtMultiIndex(MultiIndex(0,0,1))</tt> transforms 
00215    * \f$\frac{\partial}{\partial p}\f$ to 
00216    * \f$\frac{\partial}{\partial D_z p}\f$
00217    * */
00218   Deriv derivWrtMultiIndex(const MultiIndex& mi) const ;
00219 
00220   /** Whether it's possible to take a spatial derivative of this object */
00221   bool canBeDifferentiated() const ;
00222 
00223   /** \brief Return the DOF ID of my operative function, for 
00224    example, if I am \f$\frac{\partial}{\partial D_y u_x}\f$ then 
00225    return <tt>dofID</tt>\f$({\bf u})\f$.
00226    If I'm not a functional derivative,
00227    throw an error.  
00228   */
00229   int dofID() const ;
00230 
00231   /** Return the ID for my operative function */
00232   const FunctionIdentifier& fid() const ;
00233   
00234   /** Return the spatial derivative acting on my operative function */
00235   const SpatialDerivSpecifier& opOnFunc() const ;
00236 
00237   /** Indicate my algebra type */
00238   const AlgebraSpecifier& algSpec() const {return myAlgSpec_;}
00239 
00240   /** Indicate the algebra type of my operative function */
00241   const AlgebraSpecifier& funcAlgSpec() const ;
00242 
00243   /** Return a pointer to my function's data */
00244   RCP<const CommonFuncDataStub> data() const ;
00245 
00246   /** If I am a coordinate derivative, return my direction */
00247   int coordDerivDir() const ;
00248 
00249   /** Return a pointer to my operative function */
00250   const SymbolicFuncElement* symbFuncElem() const {return symbFuncElem_;}
00251 
00252   /** Return a pointer to my operative function */
00253   const SymbolicFunc* symbFunc() const {return symbFunc_;}
00254 
00255 private:
00256   /** */
00257   static AlgebraSpecifier derivAlgSpec(const AlgebraSpecifier& a,
00258     const SpatialDerivSpecifier& sds);
00259 
00260   /** */
00261   const SymbolicFuncDescriptor* sfdPtr() const ;
00262 
00263   /** */
00264   void checkConsistencyOfOperations() const ;
00265 
00266   AlgebraSpecifier myAlgSpec_;
00267 
00268   FunctionIdentifier fid_;
00269 
00270   SpatialDerivSpecifier sds_;
00271 
00272   const SymbolicFuncElement* symbFuncElem_;
00273 
00274   const SymbolicFunc* symbFunc_;
00275 
00276   int coordDerivDir_;
00277 
00278 };
00279 
00280 /** \relates Deriv */
00281 Deriv coordDeriv(int d);
00282 
00283 /** \relates Deriv */
00284 Deriv coordDeriv(const MultiIndex& mi);
00285 
00286 /** \relates Deriv */
00287 Deriv funcDeriv(const SymbolicFuncElement* symbFunc);
00288 
00289 /** \relates Deriv */
00290 Deriv funcDeriv(const SymbolicFuncElement* symbFunc, const MultiIndex& mi);
00291 
00292 /** \relates Deriv */
00293 Deriv funcDeriv(const SymbolicFunc* symbFunc);
00294 
00295 /** \relates Deriv */
00296 Deriv funcDeriv(const SymbolicFunc* symbFunc, const MultiIndex& mi);
00297 
00298 /** \relates Deriv */
00299 Deriv normalDeriv(const SymbolicFuncElement* symbFunc);
00300 
00301 Deriv divergenceDeriv(const SymbolicFunc* symbFunc);
00302 
00303  
00304 }
00305 
00306 namespace std
00307 {
00308 /** \relates Deriv */
00309 inline ostream& operator<<(std::ostream& os,  const Sundance::Deriv& d)
00310 {
00311   os << d.toString(); return os;
00312 }
00313 }
00314 
00315 
00316 #endif

Site Contact