Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Examples  

Expr.h

Go to the documentation of this file.
00001 #ifndef EXPR_H
00002 #define EXPR_H
00003 
00004 #include "SundanceDefs.h"
00005 
00006 #include "TSFArray.h"
00007 #include "BasisFamily.h"
00008 #include "DenseSerialVector.h"
00009 #include "TSFVector.h"
00010 #include "ExprHandle.h"
00011 #include "ExprArray.h"
00012 #include "LogicalExpr.h"
00013 #include "ExprBase.h"
00014 #include "Defaults.h"
00015 
00016 namespace Sundance
00017 {
00018 
00019   using namespace TSF;
00020   using std::string;
00021 
00022   using std::ostream;
00023 
00024 
00025   class MultiIndex;
00026   class QuadratureFamily;
00027   class WorkSet;
00028   class Cell;
00029   class CellSet;
00030   class AbstractFunctionSpace;
00031 
00032   /**
00033    * \ingroup UserLevelSymbolics
00034 
00035    \brief Expr represents a mathematical expression. An Expr
00036    can be an atomic entity
00037    such as a constant, a function, or a differential operator; or an expr
00038    can be a compound object such as a sum, project, or list of exprs.
00039    <A HREF="../ExprDoc.html"> More... </A>
00040 
00041   */
00042 
00043   class Expr
00044     {
00045     public:
00046       /** \name Constructors */
00047       //@{
00048       /** The empty constructor builds an uninitialized, null expr */
00049       Expr();
00050       /** Construct an Expr by assuming control of an ExprBase pointer */
00051       Expr(ExprBase* ptr);
00052       /** Construct an Expr with constant real value  */
00053       Expr(const double& value);
00054       //@}
00055       //      Expr(funcOfX f, const Expr& rangeSpecifier, const string& name="");
00056 
00057       ~Expr();
00058       Expr(const Expr& other);
00059       const Expr& operator=(const Expr& other);
00060 
00061       /** \name Math operations */
00062       //@{
00063       /** Unary minus */
00064       Expr operator-() const ;
00065       /** Reflexive add */
00066       const Expr& operator+=(const Expr& other) ;
00067       /** Reflexive subtract */
00068       const Expr& operator-=(const Expr& other) ;
00069       /** Reflexive multiply */
00070       const Expr& operator*=(const Expr& other) ;
00071       /** Reflexive divide */
00072       const Expr& operator/=(const Expr& other) ;
00073       /** Raise to a constant real power */
00074       Expr pow(const double& p) const ;
00075       //@}
00076 
00077       /** \name Listing */
00078       //@{
00079       /** read-only access to the i-th element of a list */
00080       const Expr& operator[](int i) const ;
00081       /** read/write access to the i-th element of a list */
00082       Expr& operator[](int i) ;
00083       /** the number of elements in the current level of a list */
00084       int length() const ;
00085       /** the total number of elements in all levels of a list */
00086       int size() const ;
00087       /** append a new element to a list */
00088       Expr append(const Expr& other);
00089       /** flatten a list into one dimension */
00090       Expr flatten() const ;
00091       //@}
00092 
00093       /** \name Linearization, variations, and substitution */
00094       //@{
00095       /** variation wrt a function u */
00096       Expr variation(const Expr& u) const ;
00097 
00098       /** variation of a function. Returns a test function with the same
00099        * basis as this function */
00100       Expr variation() const ;
00101 
00102       /** linearization wrt a function u about a point u0 */
00103       Expr linearization(const Expr& u, const Expr& u0) const ;
00104 
00105       /** Compute the sensitivity of an expression wrt u, evaluated
00106        * at a point u0 */
00107       Expr directSensitivity(const Expr& u, const Expr& u0) const ;
00108 
00109       /** Derive an equation for the sensitivity of u with respect
00110        * to alpha at the point alpha0 */
00111       Expr sensitivityEquation(const Expr& u, const Expr& alpha,
00112                                const Expr& alpha0) const ;
00113 
00114       /** return a function representing the unknown sensitivity of
00115        * this expr with respect to alpha */
00116       Expr sensitivity(const Expr& alpha) const ;
00117 
00118       /** differential of a function. Returns an unknown function with the
00119        * same basis as this function */
00120       Expr differential() const ;
00121 
00122       /** return a new expression with u0 in place of u throughout */
00123       Expr substitute(const Expr& u, const Expr& u0) const ;
00124 
00125       /** differential */
00126       Expr differential(const Expr& u, const Expr& du) const ;
00127 
00128       /** set the differential of a function */
00129       void setDifferential(const Expr& du) ;
00130 
00131       /** set the variation of a function */
00132       void setVariation(const Expr& v) ;
00133 
00134       /** */
00135       void setFunctionValue(const Expr& u0) ;
00136       //@}
00137 
00138       /** \name relational operators */
00139       //@{
00140       /** equality test */
00141       LogicalExpr operator==(const Expr& other) const ;
00142       /** not-equals test */
00143       LogicalExpr operator!=(const Expr& other) const ;
00144       /** less-than test */
00145       LogicalExpr operator<(const Expr& other) const ;
00146       /** greater-than test */
00147       LogicalExpr operator>(const Expr& other) const ;
00148       /**  */
00149       LogicalExpr operator<=(const Expr& other) const ;
00150       /** greater-than test */
00151       LogicalExpr operator>=(const Expr& other) const ;
00152 
00153       /** \name Probing at a cell or group of cells */
00154       //@{
00155       /** compute average value on a cell */
00156       ExprValue average(const Cell& cell) const ;
00157       /** compute average value on a cell set */
00158       ExprValue average(const Mesh& mesh, const CellSet& cellSet) const ;
00159       /** probe value at a point */
00160       double probeAtMeshPoint(int localPointIndex) const ;
00161 
00162       /** get values at a set of points in a cell */
00163       void evaluate(const AbstractFunctionSpace& targetSpace, const TSFArray<Cell>& cells,
00164                     const TSFArray<int>& cellIndices,
00165                     const TSFArray<int>& dofIndices,
00166                     const TSFArray<Point>& x,
00167                     DenseSerialVector& values) const ;
00168 
00169       /** evaluate a functional with u0 in place of the unknown u */
00170       double evaluateFunctional(const Mesh& mesh,
00171                                 const Expr& u, const Expr& u0) const ;
00172 
00173       /** evaluate a functional */
00174       double evaluateFunctional(const Mesh& mesh) const ;
00175 
00176 
00177       //@}
00178 
00179       /** */
00180       const Expr& getRegionalExpr(const string& region) const ;
00181 
00182       /** */
00183       bool isDefinedOnRegion(const string& region) const ;
00184 
00185       /** */
00186       void setRegionalExpr(const string& region, const Expr& expr);
00187 
00188       /** \name Integrals and Norms */
00189       //@{
00190 
00191       /** Integral over all maximal cells of the specified mesh, using the
00192        * specified quadrature family.*/
00193       double integral(const Mesh& mesh,
00194                       const QuadratureFamily& quad = Defaults::quadratureFamily()) const ;
00195 
00196       /** Integral over the specified cell set using default quadrature */
00197       double integral(const Mesh& mesh,
00198                       const CellSet& cellSet,
00199                       const QuadratureFamily& quad = Defaults::quadratureFamily()) const ;
00200 
00201       /** Integral over all maximal cells of the implied mesh, using the
00202        * specified quadrature family.*/
00203       double integral(const QuadratureFamily& quad = Defaults::quadratureFamily()) const ;
00204 
00205       /** Integral over the specified cell set of the implied mesh
00206        * using the specified quadrature family */
00207       double integral(const CellSet& cellSet,
00208                       const QuadratureFamily& quad = Defaults::quadratureFamily()) const ;
00209 
00210       /** L-p norm over all maximal cells of the specified mesh, using the
00211        * specified quadrature family.*/
00212       double norm(int p,
00213                   const Mesh& mesh,
00214                   const QuadratureFamily& quad = Defaults::quadratureFamily()) const ;
00215 
00216       /** L-p norm over the specified cell set using default quadrature */
00217       double norm(int p,
00218                   const Mesh& mesh,
00219                   const CellSet& cellSet,
00220                   const QuadratureFamily& quad = Defaults::quadratureFamily()) const ;
00221 
00222       /** L-p norm over all maximal cells of the implied mesh, using the
00223        * specified quadrature family.*/
00224       double norm(int p,
00225                   const QuadratureFamily& quad = Defaults::quadratureFamily()) const ;
00226 
00227       /** L-p norm over the specified cell set of the implied mesh
00228        * using the specified quadrature family */
00229       double norm(int p,
00230                   const CellSet& cellSet,
00231                   const QuadratureFamily& quad = Defaults::quadratureFamily()) const ;
00232 
00233       /** quick L-2 norm of underlying vector. This takes no account of cell areas and
00234        * is therefore not necessarily the L2 norm of the expression. It will suffice
00235        * for some purposes, however, and is fast because it doesn't have to do
00236        * any integration. */
00237       double quickNorm() const ;
00238 
00239       /** L-infinity norm */
00240       double maxNorm() const ;
00241       //@}
00242 
00243       /** \name Output */
00244       //@{
00245       /** return a string representation of an Expr */
00246       string toString(bool paren=false) const ;
00247       /** return a very verbose representation of an Expr */
00248       string fullForm() const ;
00249       /** return an XML representation of an Expr */
00250       XMLObject toXML() const ;
00251       /** write a discrete scalar function to a matlab file */
00252       void matlabDump(ostream& os) const ;
00253       /** print all discrete functions in this expr */
00254       void printDiscreteFunctions(ostream& os) const ;
00255       //@}
00256 
00257       /** \name Low-level methods -- not for user-level code */
00258       //@{
00259       /** low-level differential */
00260       void differential(const Expr& u, const Expr& du, Expr& result) const ;
00261 
00262       /**   take derivative */
00263       Expr derivative(const MultiIndex& d) const ;
00264       /**   get multiindex */
00265       const MultiIndex& multiIndex() const ;
00266 
00267       /**  Replace rvalue of LHS ptr with contents of RHS  */
00268       const Expr& assignUsingLHSPtr(const Expr& other);
00269       /**  Replace LHS ptr with RHS ptr */
00270       const Expr& assignUsingRHSPtr(const Expr& other);
00271 
00272       /**  Get the real value of a constant real Expr */
00273       double value() const ;
00274       void setParameterValue(const double& alpha);
00275       /**  Get the name of a function */
00276       const string& name() const ;
00277 
00278       /** Create a HoldExpr from this one, preventing it from being expanded.
00279        * This can save computation time in certain contexts, e.g., norms and
00280        * integrals, by reducing the number of monomials that must be processed. */
00281       Expr hold() const ;
00282 
00283       /** evaluate a scalar expr on a workset */
00284       void evaluate(const WorkSet& workSet,
00285                     const QuadratureFamily& quadFamily,
00286                     DenseSerialVector& result) const ;
00287 
00288       /** */
00289       void watchOn() ;
00290       /** */
00291       void watchOff() ;
00292 
00293       /** */
00294       bool watching() const ;
00295 
00296       /**  return the vector associated with a discrete function */
00297       void getVector(TSFVector& vector) const ;
00298 
00299       /**  set the vector associated with a discrete function */
00300       void setVector(const TSFVector& vector) ;
00301 
00302       /** read a vector of values from a file */
00303       void readValues(const string& filename) ;
00304 
00305       /** return the DOF map associated with a discrete function */
00306       void getDOFMap(TSFSmartPtr<DOFMapBase>& map) const ;
00307 
00308       /** return the index of a discrete function into a list */
00309       int getReducedIndex() const ;
00310 
00311       /**  true if two exprs are structurally and numerically equal */
00312       //      bool operator==(const Expr& other) const ;
00313       bool equals(const Expr& other) const ;
00314       /**  test if LHS is < RHS */
00315       bool lessThan(const Expr& other) const ;
00316       /**  test if LHS is > RHS */
00317       bool greaterThan(const Expr& other) const ;
00318 
00319       /**  return the sorting key of the subtype handled by this expr */
00320       int sortPriority() const ;
00321 
00322       /**  True if Expr is null */
00323       bool isNull() const {return handle()==0;}
00324       /**  True if Expr's numerical value is identically zero */
00325       bool isZero() const ;
00326       /**  True if Expr is a constant */
00327       bool isConstant() const ;
00328       /**  True if Expr is a sum */
00329       bool isSumExpr() const ;
00330       /**  True if Expr is a product */
00331       bool isProductExpr() const ;
00332       /**  True if Expr is a TermList */
00333       bool isTermListExpr() const ;
00334       /**  True if Expr is a function */
00335       bool isFuncExpr() const ;
00336       /**  True is Expr is a differentiation operator */
00337       bool isDerivative() const ;
00338       /**  True if Expr is an Expr times a derivative */
00339       bool isDiffOp() const ;
00340       /**  True if Expr is a variational function */
00341       bool isVariational() const ;
00342       /**  True if Expr is an unknown function */
00343       bool isUnknown() const ;
00344       /**  True if Expr is a coordinate function */
00345       bool isCoordExpr() const ;
00346       /**  True if Expr is a discrete function */
00347       bool isDiscreteFunction() const ;
00348       /**  True if expr is a user-defined function */
00349       bool isUserFuncExpr() const ;
00350       /**  True if expr is a design parameter */
00351       bool isParameterExpr() const ;
00352       /**  True if expr is a hold expr */
00353       bool isHoldExpr() const ;
00354       /**  True if expr is a regional expr */
00355       bool isRegionalExpr() const ;
00356       /**  True if expr is a cell diameter expr */
00357       bool isCellDiameterExpr() const ;
00358       /**  True if expr is a cell normal expr */
00359       bool isCellNormalExpr() const ;
00360       /**  True if expr is an integral expr */
00361       bool isIntegralExpr() const ;
00362       /** */
00363       bool isTestParameter() const ;
00364       /** */
00365       bool isUnknownParameter() const ;
00366       /** returns true if expr structurally constant in space */
00367       bool isSpatiallyConstant() const ;
00368 
00369       /** returns true if the expression contains an unknown */
00370       bool containsUnknown() const ;
00371       /** returns true if the expression contains a test function */
00372       bool containsTest() const ;
00373       /** returns true if the expression contains an unknown parameter */
00374       bool containsUnknownParameter() const ;
00375       /** returns true if the expression contains a test parameter */
00376       bool containsTestParameter() const ;
00377 
00378       /** */
00379       bool hasChildren() const ;
00380 
00381       /** */
00382       void getChildren(ExprArray& children) const ;
00383 
00384 
00385       /** Look up the function index of a function expr */
00386       int funcID() const ;
00387 
00388       /** return the constant term in a sum, or the constant factor
00389           in a product */
00390       double constant() const ;
00391 
00392       /** access the ExprBase pointer contained in the handle */
00393       const ExprBase* ptr() const {return handle()->ptr();}
00394 
00395       /** Find a possible constant factor in a product, and return the rremaining
00396           Expr */
00397       Expr extractPrefactor(double& prefactor) const ;
00398 
00399       /** do a deep copy of an expr */
00400       Expr clone() const ;
00401 
00402       /** check to see if the LHS appears on the RHS, e.g. x=x+y */
00403       bool lhsAppearsOnRHS(const Expr& lhs) const;
00404       /** */
00405       void replaceWithCloneOfAssignmentLHS(const Expr& lhs,
00406                                            const Expr& lhsClone);
00407       /** print */
00408       void print(ostream& os, bool paren=false) const ;
00409 
00410 
00411       /** return the basis of a function */
00412       BasisFamily getBasis() const ;
00413       /** count the number of irreducable monomials in an expr */
00414       int countMonomials() const ;
00415       /** return a list of the irreducable monomials in an expr */
00416       ExprArray getMonomials() const ;
00417       /** low-level function used in getMonomials() */
00418       void getMonomials(ExprArray& monomials, int& offset) const ;
00419       /** partition a monomial into a coeff, an unknown, and a test function.
00420        * If the monomial contains more than one unknown or test function,
00421        * or if it contains no test function, it is not a valid weak form
00422        * and this function will return false. If valid, return true. */
00423       bool getValidWeakForm(Expr& coeff, Expr& var, Expr& unk) const ;
00424 
00425       bool getMesh(Mesh& mesh) const ;
00426       /** get the cell sets on which this function is defined */
00427       void getDomain(TSFNonDupArray<CellSet>& domain) const ;
00428 
00429       //@}
00430       // letting these guys be friends of Expr saves a copy operation
00431       /** create a list containing one expr */
00432       friend Expr List(const Expr& a);
00433       /** create a list of two exprs */
00434       friend Expr List(const Expr& a, const Expr& b);
00435       /** create a list of three exprs */
00436       friend Expr List(const Expr& a, const Expr& b, const Expr& c);
00437       /** create a list of four exprs */
00438       friend Expr List(const Expr& a, const Expr& b, const Expr& c, const Expr& d);
00439 
00440       int hashCode() const ;
00441 
00442       static Expr& dummy();
00443 
00444 
00445     private:
00446       void considerSuicide();
00447       bool readyToDie() const ;
00448       void initializeRefCount();
00449       void initializeHandle(ExprHandle* handlePtr);
00450       void decrementRefCount() {(*refCount_)--;}
00451       void incrementRefCount() {(*refCount_)++;}
00452       ExprBase* ptr() {return handle()->ptr();}
00453       void nullCheck(const string& funcName) const ;
00454       ExprHandle* handle() {return *ptrToHandle_;}
00455       const ExprHandle* handle() const {return *ptrToHandle_;}
00456 
00457 
00458       ExprHandle** ptrToHandle_;
00459       int* refCount_;
00460 
00461     };
00462 
00463 
00464   inline string toString(const Expr& expr)
00465     {
00466       return expr.toString();
00467     }
00468 
00469 
00470   inline ostream& operator<<(ostream& os, const Expr& expr)
00471     {
00472       expr.print(os);
00473       return os;
00474     }
00475 
00476   inline int hashCode(const Expr& expr)
00477     {
00478       return expr.hashCode();
00479     }
00480 
00481   /**
00482    * \relates Expr
00483    * Join two exprs e1 and e2 to form a list {e1, e2}
00484    */
00485   Expr join(const Expr& e1, const Expr& e2);
00486 
00487 
00488   /**
00489    * \relates Expr
00490    * Add a and b. Both terms must have the same list structure.
00491    */
00492   Expr operator+(const Expr& a, const Expr& b);
00493 
00494   /**
00495    * \relates Expr
00496    * Subtract b from a. Both terms must have the same list structure.
00497    */
00498   Expr operator-(const Expr& a, const Expr& b);
00499 
00500   /**
00501    * \relates Expr
00502    * Multiply a and b.
00503    */
00504   Expr operator*(const Expr& a, const Expr& b);
00505 
00506   /**
00507    * \relates Expr
00508    * Divide a and b. The denominator must be a scalar-valued expr.
00509    */
00510   Expr operator/(const Expr& a, const Expr& b);
00511 
00512   /**
00513    * \relates Expr
00514    * Raise an expr to a constant real power. The expr must be scalar valued.
00515    */
00516   Expr pow(const Expr& expr, const double& p);
00517 
00518 
00519   Expr Scalar();
00520 
00521   /** \relates Expr
00522    * Create a non-expandable version of an expression
00523    */
00524   Expr hold(const Expr& expr);
00525 }
00526 #endif

Contact:
Kevin Long (krlong@ca.sandia.gov)


Documentation generated by