SundanceExpr.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_EXPR_H
00043 #define SUNDANCE_EXPR_H
00044 
00045 #include "SundanceDefs.hpp"
00046 #include "SundanceExprBase.hpp"
00047 #include "SundanceFunctionIdentifier.hpp"
00048 #include "SundanceMap.hpp"
00049 #include "PlayaHandle.hpp"
00050 #include "Teuchos_RefCountPtr.hpp"
00051 #include "Teuchos_TimeMonitor.hpp"
00052 #include <complex>
00053 
00054 
00055 namespace Sundance
00056 {
00057 
00058 class ScalarExpr;
00059 class FuncElementBase;
00060 
00061 using namespace Sundance;
00062 /**
00063  * User-level expression class. Expr is a handle to a
00064  * reference-counted pointer to a ExprBase subtype. As such,
00065  * expression copies and assignments are shallow.
00066  *
00067  * <h2> Lists </h2>
00068  *
00069  * Expressions can be grouped into lists with an arbitrary structure. Important
00070  * special cases are scalar, vector, and tensor expressions.
00071  *
00072  * <h3> Creating Lists </h3>
00073  *
00074  * <ul>
00075  * <li> Vector expressions
00076  * \code
00077  * Expr v = List(vx, vy, vz);
00078  * \endcode
00079  * <li> Heterogeneous lists
00080  * \code
00081  * // Form vector {vx, vy, vz} 
00082  * Expr v = List(vx, vy, vz);
00083  * Expr q = new TestFunction(new Lagrange(1));
00084  * // Form heterogeneous list {{vx, vy, vz}, q}
00085  * Expr state = List(v, q);
00086  * \endcode
00087  * </ul>   
00088  *
00089  * <h3> Probing Lists </h3>
00090  *
00091  * <ul>
00092  * <li> Finding the size of the top level of a list
00093  * \code
00094  * // Form vector {vx, vy, vz} 
00095  * Expr v = List(vx, vy, vz);
00096  * Expr q = new TestFunction(new Lagrange(1));
00097  * // Form heterogeneous list {{vx, vy, vz}, q}
00098  * Expr state = List(v, q);
00099  * // Check top-level size of state list {{vx, vy, vz}, q}
00100  * int stateSize = state.size(); // returns 2
00101  * \endcode
00102  * <li> Finding the total size of a list
00103  * \code
00104  * // Check total size of state list 
00105  * int totalSize = state.totalSize(); // returns 4
00106  * \endcode
00107  * </ul>
00108  * 
00109  * <h3> Manipulating Lists </h3>
00110  * 
00111  * 
00112  * 
00113  * <h2> Arithmetic Operations </h2>
00114  *
00115  * <ul>
00116  * <li> Addition
00117  * \code
00118  * Expr sum = x + y;
00119  * \endcode
00120  * The operands must have identical list structures.
00121  *
00122  * <li> Subtraction
00123  * \code
00124  * Expr diff = x - y;
00125  * \endcode
00126  * The operands must have identical list structures.
00127  * 
00128  * <li> Multiplication
00129  * \code
00130  * Expr product = x * y;
00131  * \endcode
00132  * The operands must have list
00133  * structures such that the product can be interpreted as a
00134  * scalar-vector product or as an inner product between vectors
00135  * or tensors. The multiplication operator is also used to
00136  * represent the application of a differential operator.
00137  *
00138  * <li> Division
00139  * \code
00140  * Expr quotient = x / y;
00141  * \endcode
00142  * The denominator must be scalar-valued.
00143  * </ul>
00144  *
00145  * <h2> Expression Subtypes </h2>
00146  * The user-level expression subtypes are listed below, along with examples of their use.
00147  * <ul>
00148  * <li> UnknownFunction - Represents an unknown function in a finite-element problem.
00149  * Unknown functions can be scalar-valued or vector valued.
00150  *
00151  * Example of creation of a scalar-valued unknown function:
00152  * \code
00153  * Expr u = new UnknownFunction(new Lagrange(1));
00154  * \endcode
00155  *
00156  * Example of creation of a vector-valued unknown function:
00157  * \code
00158  * Expr u = new UnknownFunction(List(new Lagrange(1), new Lagrange(1)));
00159  * \endcode
00160  *
00161  * <li> TestFunction - Represents a test function in a finite-element problem.
00162  * Test functions can be scalar-valued or vector valued.
00163  *
00164  * Example of creation of a scalar-valued test function:
00165  * \code
00166  * Expr v = new TestFunction(new Lagrange(1));
00167  * \endcode
00168  *
00169  * Example of creation of a vector-valued test function:
00170  * \code
00171  * Expr u = new TestFunction(List(new Lagrange(1), new Lagrange(1)));
00172  * \endcode
00173  * 
00174  * <li> Derivative - Represents a spatial derivative operator. 
00175  * Spatial derivatives are applied
00176  * using the multiplication operator. 
00177  * \code
00178  * Expr dx = new Derivative(0);
00179  * Expr convect = (u*dx)*u;
00180  * \endcode
00181  * Derivative expressions are scalar valued. However, vector differential operators
00182  * can be created using the List operator. For example,
00183  * \code
00184  * Expr dx = new Derivative(0);
00185  * Expr dy = new Derivative(1);
00186  * Expr grad = List(dx, dy);
00187  * \endcode
00188  * 
00189  * <li> CoordExpr - Represents a coordinate functions. 
00190  * \code
00191  * Expr x = new CoordExpr(0);
00192  * Expr y = new CoordExpr(1);
00193  * Expr r = sqrt(x*x + y*y);
00194  * \endcode
00195  * Coordinate expressions are scalar valued.
00196  *
00197  * <li> CellDiameterExpr - Represents the diameter of a cell. Cell
00198  * diameters are often used in stabilized methods. 
00199  * \code
00200  * Expr h = new CellDiameterExpr();
00201  * Expr streamlineDiffusion = eps*h*h*((u*grad)*v)*((u*grad)*T);
00202  * \endcode
00203  * Cell diameter expressions are scalar valued.
00204  * </ul>
00205  */
00206 class Expr : public Playa::Handle<ExprBase>
00207 {
00208 public:
00209   /* boilerplate handle ctors */
00210   HANDLE_CTORS(Expr, ExprBase);
00211 
00212   /** Construct with a constant. Creates a ConstantExpr. */
00213   Expr(const double& c);
00214 
00215   /** Construct with a complex constant. Creates a ComplexExpr. */
00216   Expr(const std::complex<double>& c);
00217 
00218   /** Add two expressions. The operands must have identical list
00219    * structures.
00220    */
00221   Expr operator+(const Expr& other) const ;
00222   /** Subtract two expressions. The operands must have identical
00223    *  list structures. */
00224   Expr operator-(const Expr& other) const ;
00225   /** Multiply two expressions. The operands must have list
00226    * structures such that the product can be interpreted as a
00227    * scalar-vector product or as an inner product between vectors
00228    * or tensors. The multiplication operator is also used to
00229    * represent the application of a differential operator.
00230    */
00231   Expr operator*(const Expr& other) const ;
00232   /** Divide one expression by another. The right operand must be
00233       a scalar. */
00234   Expr operator/(const Expr& other) const ;
00235 
00236   /** Divide an expression by a double. */
00237   Expr operator/(const double& other) const 
00238     {return operator*(1.0/other);}
00239 
00240   /** Divide an expression by a complex. */
00241   Expr operator/(const std::complex<double>& other) const 
00242     {return operator*(1.0/other);}
00243 
00244   /** Unary minus operator */
00245   Expr operator-() const ;
00246 
00247   /** Return real part of a complex expression */
00248   Expr real() const ;
00249 
00250   /** Return imaginary part of a complex expression */
00251   Expr imag() const ;
00252 
00253   /** Return complex conjugate */
00254   Expr conj() const ;
00255 
00256 
00257   /** List element accessor */
00258   const Expr& operator[](int i) const ;
00259       
00260   /** Number of elements in top level of list */
00261   int size() const ;
00262 
00263   /** Total number of elements in list. */
00264   int totalSize() const ;
00265 
00266   /** Append a new element to this list */
00267   void append(const Expr& expr);
00268 
00269   /** Flatten this list */
00270   Expr flatten() const ;
00271 
00272   /** Flatten list and spectral structure */
00273   Expr flattenSpectral() const ;
00274 
00275   /** */
00276   std::string toString() const ;
00277 
00278   /** */
00279   XMLObject toXML() const ;
00280 
00281   /** */
00282   bool isComplex() const ;
00283 
00284   /** */
00285   bool isSpectral() const;
00286 
00287   /** */
00288   bool isTestElement() const ;
00289 
00290   /** */
00291   bool isUnknownElement() const ;
00292 
00293   /** */
00294   void setParameterValue(const double& value);
00295   /** */
00296   double getParameterValue() const ;
00297 
00298   /** Indicate whether the expression is independent of the given 
00299    * functions */
00300   bool isIndependentOf(const Expr& u) const ;
00301 
00302   
00303   /** 
00304    * Indicate whether the expression is nonlinear 
00305    * with respect to test functions */
00306   bool isLinearInTests() const ;
00307 
00308   /** 
00309    * Indicate whether every term in the expression contains test functions */
00310   bool everyTermHasTestFunctions() const ;
00311 
00312   /** 
00313    * Indicate whether the expression contains test functions */
00314   bool hasTestFunctions() const ;
00315 
00316   /** Indicate whether the expression is linear in the given 
00317    * functions */
00318   bool isLinearForm(const Expr& u) const ;
00319 
00320   /** Indicate whether the expression is quadratic in the given 
00321    * functions */
00322   bool isQuadraticForm(const Expr& u) const ;
00323 
00324   /** Find the unknown functions appearing in this expression */
00325   void getUnknowns(Set<int>& unkID, Array<Expr>& unks) const ;
00326 
00327   /** Find the test functions appearing in this expression */
00328   void getTests(Set<int>& testID, Array<Expr>& tests) const ;
00329 
00330 
00331 #ifndef DOXYGEN_DEVELOPER_ONLY
00332 
00333      
00334 
00335   /**
00336    * Turn evaluation caching on
00337    */
00338   static bool& evaluationCachingOn() {static bool rtn = true; return rtn;}
00339 
00340   /**
00341    * Show parentheses around every pair of operands
00342    */
00343   static bool& showAllParens() {static bool rtn = false; return rtn;}
00344 
00345   /** Create a new handle for an existing ptr.  */
00346   static Expr handle(const RCP<ExprBase>& ptr)
00347     {return Expr(ptr);}
00348 
00349   /** */
00350   static Time& opTimer() 
00351     {
00352       static RCP<Time> rtn 
00353         = TimeMonitor::getNewTimer("Expr symbolic ops"); 
00354       return *rtn;
00355     }
00356   /** */
00357   static Time& outputTimer() 
00358     {
00359       static RCP<Time> rtn 
00360         = TimeMonitor::getNewTimer("Expr output"); 
00361       return *rtn;
00362     }
00363 
00364   /** Comparison operator for ordering expr trees, DO NOT use for comparison
00365    * of numerical values. */
00366   bool lessThan(const Expr& other) const ;
00367 
00368   /** Comparison operator for ordering expr trees, DO NOT use for comparison
00369    * of numerical values. */
00370   bool operator<(const Expr& other) const ;
00371 
00372   /** Equality test operator for ordering expr trees, DO NOT use for comparison
00373    * of numerical values. */
00374   bool sameAs(const Expr& other) const ;
00375 
00376   /** */
00377   Sundance::Map<Expr, int> getSumTree() const ;
00378 
00379 
00380 
00381   /** */
00382   const ScalarExpr* scalarExpr() const ;
00383 
00384   /** */
00385   const FuncElementBase* funcElement() const ;
00386 
00387 private:
00388 
00389       
00390 
00391   /** Add two scalar expressions */
00392   Expr sum(const Expr& other, int sign) const ;
00393 
00394   /** Multiply two scalar expressions */
00395   Expr multiply(const Expr& other) const ;
00396 
00397   /** Divide two scalar expressions */
00398   Expr divide(const Expr& other) const ;
00399 
00400   /** Try transformations of complex addition */
00401   bool tryAddComplex(const Expr& L, const Expr& R, int sign,
00402     Expr& rtn) const ;
00403       
00404   /** Try transformations of complex multiplication */
00405   bool tryMultiplyComplex(const Expr& L, const Expr& R, 
00406     Expr& rtn) const ;
00407 
00408 
00409 
00410 
00411 #endif /* DOXYGEN_DEVELOPER_ONLY */
00412 };
00413 
00414 /** \relates Expr */
00415 inline std::ostream& operator<<(std::ostream& os, const Expr& e)
00416 {
00417   if (e.ptr().get()==0) {os << "Expr()"; return os;}
00418   return e.ptr()->toText(os, false);
00419 }
00420 
00421 /** \relates Expr */
00422 inline Expr operator+(const double& a, const Expr& x)
00423 {return Expr(a) + x;}
00424 
00425 /** \relates Expr */
00426 inline Expr operator-(const double& a, const Expr& x)
00427 {return Expr(a) - x;}
00428 
00429 /** \relates Expr */
00430 inline Expr operator*(const double& a, const Expr& x)
00431 {return Expr(a) * x;}
00432 
00433 /** \relates Expr */
00434 inline Expr operator/(const double& a, const Expr& x)
00435 {return Expr(a) / x;}
00436 
00437 /** \relates Expr */
00438 inline Expr operator+(const std::complex<double>& a, const Expr& x)
00439 {return Expr(a) + x;}
00440 
00441 /** \relates Expr */
00442 inline Expr operator-(const std::complex<double>& a, const Expr& x)
00443 {return Expr(a) - x;}
00444 
00445 /** \relates Expr */
00446 inline Expr operator*(const std::complex<double>& a, const Expr& x)
00447 {return Expr(a) * x;}
00448 
00449 /** \relates Expr */
00450 inline Expr operator/(const std::complex<double>& a, const Expr& x)
00451 {return Expr(a) / x;}
00452 
00453 /** \relates Expr */
00454 inline Expr Re(const Expr& a) {return a.real();}
00455 
00456 /** \relates Expr */
00457 inline Expr Im(const Expr& a) {return a.imag();}
00458 
00459 /** \relates Expr */
00460 inline Expr conj(const Expr& a) {return a.conj();}
00461 
00462 /** \relates Expr */
00463 Expr Complex(const Expr& real, const Expr& imag);
00464 
00465 /** \relates Expr */
00466 Expr List(const Expr& a);
00467 
00468 /** \relates Expr */
00469 Expr List(const Expr& a, const Expr& b);
00470 
00471 /** \relates Expr */
00472 Expr List(const Expr& a, const Expr& b, const Expr& c);
00473 
00474 /** \relates Expr */
00475 Expr List(const Expr& a, const Expr& b, const Expr& c,
00476   const Expr& d);
00477 
00478 /** \relates Expr */
00479 Expr List(const Expr& a, const Expr& b, const Expr& c,
00480   const Expr& d, const Expr& e);
00481 
00482 /** \relates Expr */
00483 Expr List(const Expr& a, const Expr& b, const Expr& c,
00484   const Expr& d, const Expr& e, const Expr& f);
00485 
00486 /** \relates Expr */
00487 Expr List(const Expr& a, const Expr& b, const Expr& c,
00488   const Expr& d, const Expr& e, const Expr& f,
00489   const Expr& g);
00490 
00491 
00492 /** \relates Expr */
00493 Expr List(const Expr& a, const Expr& b, const Expr& c,
00494   const Expr& d, const Expr& e, const Expr& f,
00495   const Expr& g, const Expr& h);
00496 
00497 /** \relates Expr */
00498 Expr List(const Expr& a, const Expr& b, const Expr& c,
00499   const Expr& d, const Expr& e, const Expr& f,
00500   const Expr& g, const Expr& h, const Expr& i);
00501 
00502 /** \relates Expr */
00503 Expr List(const Expr& a, const Expr& b, const Expr& c,
00504   const Expr& d, const Expr& e, const Expr& f,
00505   const Expr& g, const Expr& h, const Expr& i,
00506   const Expr& j);
00507 
00508 
00509   
00510 
00511 }
00512 
00513 #endif

Site Contact