00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 #include "SundanceSymbolicFuncElement.hpp"
00032 #include "SundanceSymbolicFunc.hpp"
00033 #include "SundanceDiscreteFuncElement.hpp"
00034 #include "SundanceTestFuncElement.hpp"
00035 #include "SundanceZeroExpr.hpp"
00036 
00037 #include "SundanceDerivSet.hpp"
00038 #include "PlayaTabs.hpp"
00039 
00040 
00041 using namespace Sundance;
00042 using namespace Sundance;
00043 
00044 using namespace Sundance;
00045 using namespace Teuchos;
00046 
00047 
00048 
00049 SymbolicFuncElement::SymbolicFuncElement(const std::string& name,
00050   const std::string& suffix,
00051   const FunctionIdentifier& fid,
00052   const RCP<const CommonFuncDataStub>& data)
00053   : EvaluatableExpr(), FuncElementBase(name, suffix, fid),
00054     commonData_(data),
00055     evalPt_(),
00056     evalPtDerivSetIndices_()
00057 {}
00058 
00059 void SymbolicFuncElement::registerSpatialDerivs(const EvalContext& context, 
00060   const Set<MultiIndex>& miSet) const
00061 {
00062   evalPt()->registerSpatialDerivs(context, miSet);
00063   EvaluatableExpr::registerSpatialDerivs(context, miSet);
00064 }
00065 
00066 void SymbolicFuncElement::accumulateFuncSet(Set<int>& funcDofIDs, 
00067   const Set<int>& activeSet) const
00068 {
00069   if (activeSet.contains(fid().dofID())) 
00070   {
00071     funcDofIDs.put(fid().dofID());
00072   }
00073 }
00074 
00075 
00076 Set<MultipleDeriv> 
00077 SymbolicFuncElement::internalFindW(int order, const EvalContext& context) const
00078 {
00079   Tabs tab(0);
00080   int verb = context.setupVerbosity();
00081   SUNDANCE_MSG2(verb, tab << "SFE::internalFindW(order=" << order << ") for "
00082     << toString());
00083 
00084   Set<MultipleDeriv> rtn;
00085 
00086   {
00087     Tabs tab1;
00088     SUNDANCE_MSG2(verb, tab1 << "findW() for eval point");
00089     evalPt()->findW(order, context);
00090   }
00091 
00092   if (order==0) 
00093   {
00094     Tabs tab1;
00095     if (!evalPtIsZero()) 
00096     {
00097       SUNDANCE_MSG5(verb, tab1 << "value of " << toString() << " is nonzero" );
00098       rtn.put(MultipleDeriv());
00099     }
00100     else
00101     {
00102       SUNDANCE_MSG5(verb,  tab1 << "value of " << toString() << " is zero" );
00103     }
00104   }
00105   else if (order==1)
00106   {
00107     Deriv d = funcDeriv(this);
00108     MultipleDeriv md;
00109     md.put(d);
00110     rtn.put(md);
00111   }
00112   
00113   SUNDANCE_MSG2(verb,  tab << "SFE: W[" << order << "] = " << rtn );
00114 
00115   return rtn;
00116 }
00117 
00118 
00119 Set<MultipleDeriv> 
00120 SymbolicFuncElement::internalFindV(int order, const EvalContext& context) const
00121 {
00122   Tabs tab(0);
00123   int verb = context.setupVerbosity();
00124   SUNDANCE_MSG2(verb, tab << "SFE::internalFindV(order=" << order << ") for "
00125     << toString());
00126   Set<MultipleDeriv> rtn;
00127 
00128   {
00129     Tabs tab1;
00130     SUNDANCE_MSG2(verb, tab1 << "findV() for eval point");
00131     evalPt()->findV(order, context);
00132   }
00133 
00134   if (order==0) 
00135   {
00136     if (!evalPtIsZero()) rtn.put(MultipleDeriv());
00137   }
00138 
00139   SUNDANCE_MSG5(verb,  tab << "SFE: V = " << rtn );
00140   SUNDANCE_MSG5(verb,  tab << "SFE: R = " << findR(order, context) );
00141   rtn = rtn.intersection(findR(order, context));
00142 
00143   SUNDANCE_MSG2(verb,  tab << "SFE: V[" << order << "] = " << rtn );
00144   return rtn;
00145 }
00146 
00147 
00148 Set<MultipleDeriv> 
00149 SymbolicFuncElement::internalFindC(int order, const EvalContext& context) const
00150 {
00151   Tabs tab(0);
00152   int verb = context.setupVerbosity();
00153   SUNDANCE_MSG2(verb, tab << "SFE::internalFindC(order=" << order << ") for "
00154     << toString());
00155   Set<MultipleDeriv> rtn;
00156 
00157   {
00158     Tabs tab1;
00159     SUNDANCE_MSG2(verb, tab1 << "findC() for eval point");
00160     evalPt()->findC(order, context);
00161   }
00162 
00163   if (order==1)
00164   {
00165     Deriv d(funcDeriv(this));
00166     MultipleDeriv md;
00167     md.put(d);
00168     rtn.put(md);
00169   }
00170 
00171   rtn = rtn.intersection(findR(order, context));
00172 
00173   SUNDANCE_MSG2(verb,  tab << "SFE: C[" << order << "] = " << rtn );
00174   return rtn;
00175 }
00176 
00177 
00178 RCP<Array<Set<MultipleDeriv> > > SymbolicFuncElement
00179 ::internalDetermineR(const EvalContext& context,
00180   const Array<Set<MultipleDeriv> >& RInput) const
00181 {
00182   Tabs tab(0);
00183   int verb = context.setupVerbosity();
00184   SUNDANCE_MSG2(verb, tab << "SFE::internalDetermineR() for "
00185     << toString());
00186   {
00187     Tabs tab1;
00188     SUNDANCE_MSG3(verb, tab1 << "determineR() for eval point");
00189     evalPt()->determineR(context, RInput);
00190 
00191     SUNDANCE_MSG3(verb, tab1 << "SFE::internalDetermineR() for "
00192       << toString() << " delegating to EE");
00193     return EvaluatableExpr::internalDetermineR(context, RInput);
00194   }
00195 }
00196 
00197 bool SymbolicFuncElement::evalPtIsZero() const
00198 {
00199   TEUCHOS_TEST_FOR_EXCEPTION(evalPt_.get()==0, std::logic_error,
00200     "null evaluation point in SymbolicFuncElement::evalPtIsZero()");
00201   bool isZero = 0 != dynamic_cast<const ZeroExpr*>(evalPt());
00202   bool isTest = 0 != dynamic_cast<const TestFuncElement*>(this);
00203   return isZero || isTest;
00204 }
00205 
00206 void SymbolicFuncElement::substituteZero() const 
00207 {
00208   evalPt_ = rcp(new ZeroExpr());
00209 }
00210 
00211 void SymbolicFuncElement
00212 ::substituteFunction(const RCP<DiscreteFuncElement>& u0) const
00213 {
00214   evalPt_ = u0;
00215 }
00216 
00217 
00218 
00219 bool SymbolicFuncElement::isIndependentOf(const Expr& u) const 
00220 {
00221   Expr uf = u.flatten();
00222   for (int i=0; i<uf.size(); i++)
00223   {
00224     const ExprBase* p = uf[i].ptr().get();
00225     const SymbolicFuncElement* f = dynamic_cast<const SymbolicFuncElement*>(p);
00226     TEUCHOS_TEST_FOR_EXCEPTION(f==0, std::logic_error, "expected a list of functions, "
00227       " got " << u);
00228     if (fid().dofID() == f->fid().dofID()) return false;
00229   }
00230   return true;
00231 }
00232 
00233 
00234 bool SymbolicFuncElement::isLinearForm(const Expr& u) const
00235 {
00236   Expr uf = u.flatten();
00237   for (int i=0; i<uf.size(); i++)
00238   {
00239     const ExprBase* p = uf[i].ptr().get();
00240     const SymbolicFuncElement* f = dynamic_cast<const SymbolicFuncElement*>(p);
00241     TEUCHOS_TEST_FOR_EXCEPTION(f==0, std::logic_error, "expected a list of functions, "
00242       " got " << u);
00243     if (fid().dofID() == f->fid().dofID()) return true;
00244   }
00245   return false;
00246 }
00247 
00248