SundanceEvaluatableExpr.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_EVALUATABLEEXPR_H
00043 #define SUNDANCE_EVALUATABLEEXPR_H
00044 
00045 
00046 
00047 #include "SundanceDefs.hpp"
00048 #include "SundanceScalarExpr.hpp"
00049 #include "SundanceEvaluatorFactory.hpp"
00050 #include "SundanceFuncSetAccumulator.hpp"
00051 #include "SundanceMap.hpp"
00052 #include "SundanceDerivSet.hpp"
00053 #include "SundanceEvalContext.hpp"
00054 #include "SundanceEvalVector.hpp"
00055 #include "SundanceSparsitySuperset.hpp"
00056 #include "SundanceObjectWithVerbosity.hpp"
00057 #include "Teuchos_TimeMonitor.hpp"
00058 
00059 namespace Sundance
00060 {
00061 using namespace Sundance;
00062 using namespace Teuchos;
00063 using namespace Sundance;
00064 
00065 
00066 
00067 class Expr;
00068 class MultipleDeriv;
00069 
00070 class EvalManager;
00071 class Evaluator;
00072 class EvaluatorFactory;
00073 
00074 /**
00075  *
00076  */
00077 enum DerivSubsetSpecifier {AllNonzeros, 
00078                            RequiredNonzeros,
00079                            VariableNonzeros,
00080                            ConstantNonzeros};
00081 
00082 /**
00083  *
00084  */
00085 
00086 class EvaluatableExpr : public virtual ScalarExpr,
00087                         public virtual EvaluatorFactory,
00088                         public virtual FuncSetAccumulator,
00089                         public ObjectWithClassVerbosity<EvaluatableExpr>
00090 {
00091   typedef OrderedQuartet<EvalContext, 
00092                          Set<MultiIndex>,
00093                          Set<MultiSet<int> >,
00094                          bool> NonzeroSpecifier ;
00095 
00096 
00097 public:
00098   /** Ctor is empty, but has some internal initialization to do
00099    * and so must be called by all subclasses */
00100   EvaluatableExpr();
00101 
00102   /** virtual dtor */
00103   virtual ~EvaluatableExpr(){;}
00104 
00105 
00106   /** \name Evaluation */
00107   //@{
00108   /**
00109    * Evaluate this expression in the given region, putting the results
00110    * of the evaluation in the results argument. 
00111    */
00112   void evaluate(const EvalManager& mgr,
00113     Array<double>& constantResults,
00114     Array<RCP<EvalVector> >& vectorResults) const ;
00115   //@}
00116 
00117   /** \name Preprocessing */
00118   //@{
00119   /**
00120    * 
00121    */
00122   virtual void setupEval(const EvalContext& context) const ;
00123 
00124       
00125 
00126 
00127   /** Return the set of all nonzero derivatives
00128    * required in the given context */
00129   RCP<SparsitySuperset> sparsitySuperset(const EvalContext& context) const ;
00130 
00131   //@}
00132       
00133 
00134 
00135 
00136   /** Utility to downcast an expression to an evaluatable expr. Throws
00137    * an exception if the cast fails. */
00138   static const EvaluatableExpr* getEvalExpr(const Expr& expr);
00139 
00140   /** Return the evaluator to be used for the given context */
00141   const RCP<Evaluator>& evaluator(const EvalContext& context) const; 
00142 
00143   /** */
00144   virtual void showSparsity(std::ostream& os, 
00145     const EvalContext& context) const ;
00146 
00147 
00148   /** */
00149   virtual int countNodes() const ;
00150 
00151   /**
00152    * Find the maximum differentiation order acting on discrete
00153    * functions in this expression. This is needed to identify
00154    * expressions where cofacet Jacobians are needed to transform  
00155    * discrete function derivatives.
00156    *
00157    * The base class implementation is a no-op.
00158    */
00159   virtual int maxDiffOrderOnDiscreteFunctions() const {return 0;}
00160 
00161   /**
00162    * Indicate whether this expression contains discrete functions.
00163    */
00164   virtual bool hasDiscreteFunctions() const {return false;}
00165 
00166   /** */
00167   virtual bool nodesHaveBeenCounted() const {return nodesHaveBeenCounted_;}
00168 
00169   /** */
00170   static int maxFuncDiffOrder() {static int rtn=3; return rtn;}
00171 
00172 
00173   /** */
00174   virtual Set<MultipleDeriv> 
00175   internalFindW(int order, const EvalContext& context) const = 0 ;
00176 
00177   /** Find spatially-variable functional derivatives. Default implementation
00178    * returns R */
00179   virtual Set<MultipleDeriv> 
00180   internalFindV(int order, const EvalContext& context) const
00181     {return findR(order, context);}
00182 
00183   /** Find spatially-constant functional derivatives. Default implementation
00184    * returns the empty set */
00185   virtual Set<MultipleDeriv> 
00186   internalFindC(int order, const EvalContext& context) const
00187     {Set<MultipleDeriv> rtn; return rtn;}
00188 
00189       
00190 
00191   /** */
00192   const Set<MultipleDeriv>& 
00193   findDerivSubset(int order,
00194     const DerivSubsetSpecifier& dss,
00195     const EvalContext& context) const ;
00196   /** */
00197   const Set<MultipleDeriv>& 
00198   findDerivSubset(const DerivSubsetSpecifier& dss,
00199     const EvalContext& context) const ;
00200 
00201   /** */
00202   const Set<MultipleDeriv>& findW(int order, 
00203     const EvalContext& context) const ;
00204 
00205   /** */
00206   const Set<MultipleDeriv>& findR(int order, 
00207     const EvalContext& context) const ;
00208   /** */
00209   const Set<MultipleDeriv>& findV(int order, 
00210     const EvalContext& context) const ;
00211   /** */
00212   const Set<MultipleDeriv>& findC(int order, 
00213     const EvalContext& context) const ;
00214 
00215 
00216   /** */
00217   const Set<MultipleDeriv>& findW(const EvalContext& context) const ;
00218 
00219   /** */
00220   const Set<MultipleDeriv>& findR(const EvalContext& context) const ;
00221   /** */
00222   const Set<MultipleDeriv>& findV(const EvalContext& context) const ;
00223   /** */
00224   const Set<MultipleDeriv>& findC(const EvalContext& context) const ;
00225 
00226   /** */
00227   virtual void displayNonzeros(std::ostream& os, 
00228     const EvalContext& context) const ;
00229 
00230 
00231   /** */
00232   Set<MultipleDeriv> setProduct(const Set<MultipleDeriv>& a,
00233     const Set<MultipleDeriv>& b) const ;
00234   /** */
00235   Set<MultipleDeriv> setDivision(const Set<MultipleDeriv>& a,
00236     const Set<MultipleDeriv>& b) const ;
00237   /** */
00238   Set<MultiSet<int> > setDivision(const Set<MultiSet<int> >& s,
00239     int index) const ;
00240       
00241   /** */
00242   void determineR(const EvalContext& context,
00243     const Array<Set<MultipleDeriv> >& RInput) const ;
00244 
00245   /** */
00246   virtual RCP<Array<Set<MultipleDeriv> > > 
00247   internalDetermineR(const EvalContext& context,
00248     const Array<Set<MultipleDeriv> >& RInput) const ;
00249 
00250   /** */
00251   const Set<MultipleDeriv>& getR(int order, const EvalContext& context) const ;
00252 
00253       
00254   /** */
00255   Array<Set<MultipleDeriv> > 
00256   computeInputR(const EvalContext& context,
00257     const Array<Set<MultiSet<int> > >& funcIDCombinations,
00258     const Array<Set<MultiIndex> >& spatialDerivs) const ;
00259 
00260 
00261   /** */
00262   virtual void registerSpatialDerivs(const EvalContext& context, 
00263     const Set<MultiIndex>& miSet) const ;
00264       
00265   /** */
00266   static Time& evaluationTimer() ;
00267       
00268 protected:
00269 
00270   /** Record the evaluator to be used for the given context */
00271   void registerEvaluator(const EvalContext& context,
00272     const RCP<Evaluator>& evaluator) const 
00273     {return evaluators_.put(context, evaluator);}
00274 
00275   /** */
00276   static bool isEvaluatable(const ExprBase* expr);
00277 
00278   /** */
00279   Map<EvalContext, RCP<Evaluator> >& evaluators() const 
00280     {return evaluators_;}
00281 
00282 
00283   /** */
00284   int maxOrder(const Set<MultiIndex>& m) const ;
00285 
00286   /** */
00287   const Set<MultiIndex>& activeSpatialDerivs(const EvalContext& context) const ;
00288 
00289   /** */
00290   std::string derivType(const DerivSubsetSpecifier& dss) const;
00291 
00292   /** */
00293   void printR(int verb, const RCP<Array<Set<MultipleDeriv> > >& R) const ;
00294 
00295 private:
00296       
00297   /** */
00298   static int numDerivSubsetTypes() {static int rtn=4; return rtn;}
00299 
00300   /** 
00301    * evaluators, indexed by context 
00302    */
00303   mutable Map<EvalContext, RCP<Evaluator> > evaluators_;
00304 
00305   /** 
00306    * supersets of nonzero derivatives to be computed, index by
00307    * context
00308    */
00309   mutable Map<EvalContext, RCP<SparsitySuperset> > sparsity_;
00310 
00311   /** Polynomial order of the dependency upon each coordinate direction */
00312   Array<int> orderOfDependency_;
00313 
00314   /** Set of function combinations appearing in nonzero mixed partials */ 
00315   Set<MultiSet<int> > funcIDSet_;
00316 
00317   /** */
00318   Set<int> funcDependencies_;
00319 
00320   mutable Set<NonzeroSpecifier> knownNonzeros_;
00321 
00322   mutable bool nodesHaveBeenCounted_; 
00323 
00324   typedef Array<Map<EvalContext, Set<MultipleDeriv> > > contextToDSSMap_ele_t;
00325   mutable Array<contextToDSSMap_ele_t> contextToDSSMap_;
00326 
00327   mutable bool rIsReady_;
00328 
00329   mutable Array<Map<EvalContext, Set<MultipleDeriv> > > allOrdersMap_;
00330 
00331   mutable Map<EvalContext, Set<MultiIndex> > activeSpatialDerivMap_;
00332 };
00333 }
00334 
00335 #endif

Site Contact