SundanceSymbolicFuncElement.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 // 
00007 // Copyright (year first published) Sandia Corporation.  Under the terms 
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 
00009 // retains certain rights in this software.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //                                                                                 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA                                                                                
00025 // Questions? Contact Kevin Long (krlong@sandia.gov), 
00026 // Sandia National Laboratories, Livermore, California, USA
00027 // 
00028 // ************************************************************************
00029 /* @HEADER@ */
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 

Site Contact