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
00032
00033
00034
00035
00036
00037
00038
00039
00040
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