SundanceExplicitFunctionalDerivativeElement.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 // 
00007 // Copyright (year first published) Sandia Corporation.  Under the terms 
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 
00009 // retains certain rights in this software.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //                                                                                 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA                                                                                
00025 // Questions? Contact Kevin Long (krlong@sandia.gov), 
00026 // Sandia National Laboratories, Livermore, California, USA
00027 // 
00028 // ************************************************************************
00029 /* @HEADER@ */
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 /* paren */) 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   /* all done */  
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 

Site Contact