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