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