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

Site Contact