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