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 "SundanceExplicitFunctionalDerivativeElement.hpp"
00032 
00033 #include "SundanceEFDEEvaluator.hpp"
00034 #include "PlayaTabs.hpp"
00035 #include "SundanceOut.hpp"
00036 
00037 using namespace Sundance;
00038 using namespace Sundance;
00039 
00040 using namespace Sundance;
00041 using namespace Teuchos;
00042 
00043 
00044 ExplicitFunctionalDerivativeElement
00045 ::ExplicitFunctionalDerivativeElement(
00046   const RCP<ScalarExpr>& arg,
00047   const Deriv& fd
00048   )
00049   : UnaryExpr(arg), fd_(fd)
00050 {
00051   Tabs tabs;
00052 }
00053 
00054 std::ostream& ExplicitFunctionalDerivativeElement
00055 ::toText(std::ostream& os, bool ) const 
00056 {
00057   os << "FD[" << arg().toString() << ", " << fd_ << "]";
00058   return os;
00059 }
00060 
00061 
00062 XMLObject ExplicitFunctionalDerivativeElement
00063 ::toXML() const 
00064 {
00065   XMLObject rtn("EFDE");
00066   rtn.addAttribute("df", fd_.toString());
00067   rtn.addChild(arg().toXML());
00068 
00069   return rtn;
00070 }
00071 
00072 
00073 Evaluator* ExplicitFunctionalDerivativeElement
00074 ::createEvaluator(const EvaluatableExpr* expr,
00075   const EvalContext& context) const
00076 {
00077   return new EFDEEvaluator(dynamic_cast<const ExplicitFunctionalDerivativeElement*>(expr), context);
00078 }
00079 
00080 
00081 
00082 
00083 RCP<Array<Set<MultipleDeriv> > > 
00084 ExplicitFunctionalDerivativeElement
00085 ::internalDetermineR(const EvalContext& context,
00086                            const Array<Set<MultipleDeriv> >& RInput) const
00087 {
00088   Tabs tab0(0);
00089   int verb = context.setupVerbosity();
00090   SUNDANCE_MSG2(verb, tab0 << "ExplicitFunctionalDerivativeElement::internalDetermineR for=" << toString());
00091   SUNDANCE_MSG2(verb, tab0 << "RInput = " << RInput );
00092 
00093   RCP<Array<Set<MultipleDeriv> > > rtn 
00094     = rcp(new Array<Set<MultipleDeriv> >(RInput.size()));
00095   
00096   {
00097     Tabs tab1;
00098     for (int i=0; i<RInput.size(); i++)
00099       {
00100         Tabs tab2;
00101         const Set<MultipleDeriv>& Wi = findW(i, context);
00102         SUNDANCE_MSG5(verb,  tab2 << "W[" << i << "] = " << Wi );
00103         (*rtn)[i] = RInput[i].intersection(Wi);
00104       }
00105 
00106     Array<Set<MultipleDeriv> > RArg(RInput.size()+1);
00107     MultipleDeriv me(fd_);
00108     
00109     for (int order=1; order<=RInput.size(); order++)
00110       {
00111         Tabs tab2;
00112         SUNDANCE_MSG3(verb, tab2 << "order = " << order);
00113         if (RInput[order-1].size() == 0) continue;
00114         const Set<MultipleDeriv>& WArg = evaluatableArg()->findW(order, context);
00115         const Set<MultipleDeriv>& RMinus = (*rtn)[order-1];
00116 
00117         SUNDANCE_MSG3(verb, tab2 << "RInput = " << RInput[order-1]);
00118         SUNDANCE_MSG3(verb, tab2 << "FD times RInput = " 
00119           << setProduct(RMinus, makeSet(me)));
00120         
00121         RArg[order].merge(setProduct(RMinus, makeSet(me)).intersection(WArg));
00122       }
00123     SUNDANCE_MSG3(verb, tab1 << "RArg = " << RArg);
00124     
00125     SUNDANCE_MSG3(verb, tab1 << "calling determineR() for arg "
00126                        << evaluatableArg()->toString());
00127     evaluatableArg()->determineR(context, RArg);
00128   }
00129   printR(verb, rtn);
00130   SUNDANCE_MSG2(verb, tab0 << "done with ExplicitFunctionalDerivativeElement::internalDetermineR for "
00131                      << toString());
00132     
00133   return rtn;
00134 }
00135 
00136 
00137 Set<MultipleDeriv> ExplicitFunctionalDerivativeElement
00138 ::internalFindW(int order, const EvalContext& context) const
00139 {
00140   Tabs tab0(0);
00141   int verb = context.setupVerbosity();
00142   SUNDANCE_MSG2(verb, tab0 
00143     << "ExplicitFunctionalDerivativeElement::internalFindW(order="
00144     << order << ") for " << toString());
00145 
00146 
00147   Set<MultipleDeriv> rtn ;
00148 
00149   if (order < 3)
00150   {
00151     Tabs tab1;
00152     const Set<MultipleDeriv>& WArgPlus 
00153       = evaluatableArg()->findW(order+1, context);
00154     
00155     SUNDANCE_MSG5(verb, tab1 << "WArgPlus = " << WArgPlus);
00156     MultipleDeriv me(fd_);
00157     Set<MultipleDeriv> WargPlusOslashFD = setDivision(WArgPlus, makeSet(me));
00158     SUNDANCE_MSG5(verb, tab1 << "WArgPlus / fd = " 
00159       << WargPlusOslashFD);
00160     rtn = WargPlusOslashFD;
00161   }
00162   SUNDANCE_MSG2(verb, tab0 << "W[" << order << "]=" << rtn);
00163   SUNDANCE_MSG2(verb, tab0 << "done with ExplicitFunctionalDerivativeElement::internalFindW(" << order << ") for "
00164                      << toString());
00165 
00166   return rtn;
00167 }
00168 
00169 
00170 Set<MultipleDeriv> ExplicitFunctionalDerivativeElement
00171 ::internalFindV(int order, const EvalContext& context) const
00172 {
00173   Tabs tabs(0);
00174   int verb = context.setupVerbosity();
00175   SUNDANCE_MSG2(verb, tabs << "ExplicitFunctionalDerivativeElement::internalFindV(" << order << ") for " 
00176                      << toString());
00177 
00178   Set<MultipleDeriv> rtn;
00179   
00180   {
00181     Tabs tab1;
00182     SUNDANCE_MSG5(verb, tab1 << "finding R");
00183     const Set<MultipleDeriv>& R = findR(order, context);
00184     SUNDANCE_MSG5(verb, tab1 << "finding C");
00185     const Set<MultipleDeriv>& C = findC(order, context);
00186     rtn = R.setDifference(C);
00187   }
00188   SUNDANCE_MSG2(verb, tabs << "V[" << order << "]=" << rtn);
00189   SUNDANCE_MSG2(verb, tabs << "done with ExplicitFunctionalDerivativeElement::internalFindV(" << order << ") for "
00190     << toString());
00191   
00192   return rtn;
00193 }
00194 
00195 
00196 Set<MultipleDeriv> ExplicitFunctionalDerivativeElement
00197 ::internalFindC(int order, const EvalContext& context) const
00198 {
00199   Tabs tabs(0);
00200   int verb = context.setupVerbosity();
00201   SUNDANCE_MSG2(verb, tabs << "ExplicitFunctionalDerivativeElement::internalFindC() for " 
00202     << toString());
00203   Set<MultipleDeriv> rtn ;
00204   if (order < 3) 
00205   {
00206     Tabs tab1;
00207     SUNDANCE_MSG5(verb, tab1 << "finding R");
00208     const Set<MultipleDeriv>& R = findR(order, context);
00209     SUNDANCE_MSG5(verb, tab1 << "R=" << R);
00210 
00211     SUNDANCE_MSG5(verb, tab1 << "finding C for arg");
00212     const Set<MultipleDeriv>& argC 
00213       = evaluatableArg()->findC(order+1, context);
00214     SUNDANCE_MSG5(verb, tab1 << "argC=" << argC);
00215 
00216     MultipleDeriv me(fd_);
00217     Set<MultipleDeriv> tmp = setDivision(argC, makeSet(me));
00218     rtn = tmp.intersection(R);
00219   }
00220 
00221   SUNDANCE_MSG2(verb, tabs << "C[" << order << "]=" << rtn);
00222   SUNDANCE_MSG2(verb, tabs << "done with ExplicitFunctionalDerivativeElement::internalFindC for "
00223     << toString());
00224   return rtn;
00225 }
00226 
00227 
00228 
00229 
00230 bool ExplicitFunctionalDerivativeElement
00231 ::lessThan(const ScalarExpr* other) const
00232 {
00233   const ExplicitFunctionalDerivativeElement* e 
00234     = dynamic_cast<const ExplicitFunctionalDerivativeElement*>(other);
00235   TEUCHOS_TEST_FOR_EXCEPTION(e==0, std::logic_error, "cast should never fail at this point");
00236   
00237   if (fd_ < e->fd_) return true;
00238   if (e->fd_ < fd_) return false;
00239   
00240   return ExprWithChildren::lessThan(other);
00241 }
00242