SundanceExplicitFunctionalDerivativeElement.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
00041 
00042 #include "SundanceExplicitFunctionalDerivativeElement.hpp"
00043 
00044 #include "SundanceEFDEEvaluator.hpp"
00045 #include "PlayaTabs.hpp"
00046 #include "SundanceOut.hpp"
00047 
00048 using namespace Sundance;
00049 using namespace Sundance;
00050 
00051 using namespace Sundance;
00052 using namespace Teuchos;
00053 
00054 
00055 ExplicitFunctionalDerivativeElement
00056 ::ExplicitFunctionalDerivativeElement(
00057   const RCP<ScalarExpr>& arg,
00058   const Deriv& fd
00059   )
00060   : UnaryExpr(arg), fd_(fd)
00061 {
00062   Tabs tabs;
00063 }
00064 
00065 std::ostream& ExplicitFunctionalDerivativeElement
00066 ::toText(std::ostream& os, bool /* paren */) const 
00067 {
00068   os << "FD[" << arg().toString() << ", " << fd_ << "]";
00069   return os;
00070 }
00071 
00072 
00073 XMLObject ExplicitFunctionalDerivativeElement
00074 ::toXML() const 
00075 {
00076   XMLObject rtn("EFDE");
00077   rtn.addAttribute("df", fd_.toString());
00078   rtn.addChild(arg().toXML());
00079 
00080   return rtn;
00081 }
00082 
00083 
00084 Evaluator* ExplicitFunctionalDerivativeElement
00085 ::createEvaluator(const EvaluatableExpr* expr,
00086   const EvalContext& context) const
00087 {
00088   return new EFDEEvaluator(dynamic_cast<const ExplicitFunctionalDerivativeElement*>(expr), context);
00089 }
00090 
00091 
00092 
00093 
00094 RCP<Array<Set<MultipleDeriv> > > 
00095 ExplicitFunctionalDerivativeElement
00096 ::internalDetermineR(const EvalContext& context,
00097                            const Array<Set<MultipleDeriv> >& RInput) const
00098 {
00099   Tabs tab0(0);
00100   int verb = context.setupVerbosity();
00101   SUNDANCE_MSG2(verb, tab0 << "ExplicitFunctionalDerivativeElement::internalDetermineR for=" << toString());
00102   SUNDANCE_MSG2(verb, tab0 << "RInput = " << RInput );
00103 
00104   RCP<Array<Set<MultipleDeriv> > > rtn 
00105     = rcp(new Array<Set<MultipleDeriv> >(RInput.size()));
00106   
00107   {
00108     Tabs tab1;
00109     for (int i=0; i<RInput.size(); i++)
00110       {
00111         Tabs tab2;
00112         const Set<MultipleDeriv>& Wi = findW(i, context);
00113         SUNDANCE_MSG5(verb,  tab2 << "W[" << i << "] = " << Wi );
00114         (*rtn)[i] = RInput[i].intersection(Wi);
00115       }
00116 
00117     Array<Set<MultipleDeriv> > RArg(RInput.size()+1);
00118     MultipleDeriv me(fd_);
00119     
00120     for (int order=1; order<=RInput.size(); order++)
00121       {
00122         Tabs tab2;
00123         SUNDANCE_MSG3(verb, tab2 << "order = " << order);
00124         if (RInput[order-1].size() == 0) continue;
00125         const Set<MultipleDeriv>& WArg = evaluatableArg()->findW(order, context);
00126         const Set<MultipleDeriv>& RMinus = (*rtn)[order-1];
00127 
00128         SUNDANCE_MSG3(verb, tab2 << "RInput = " << RInput[order-1]);
00129         SUNDANCE_MSG3(verb, tab2 << "FD times RInput = " 
00130           << setProduct(RMinus, makeSet(me)));
00131         
00132         RArg[order].merge(setProduct(RMinus, makeSet(me)).intersection(WArg));
00133       }
00134     SUNDANCE_MSG3(verb, tab1 << "RArg = " << RArg);
00135     
00136     SUNDANCE_MSG3(verb, tab1 << "calling determineR() for arg "
00137                        << evaluatableArg()->toString());
00138     evaluatableArg()->determineR(context, RArg);
00139   }
00140   printR(verb, rtn);
00141   SUNDANCE_MSG2(verb, tab0 << "done with ExplicitFunctionalDerivativeElement::internalDetermineR for "
00142                      << toString());
00143   /* all done */  
00144   return rtn;
00145 }
00146 
00147 
00148 Set<MultipleDeriv> ExplicitFunctionalDerivativeElement
00149 ::internalFindW(int order, const EvalContext& context) const
00150 {
00151   Tabs tab0(0);
00152   int verb = context.setupVerbosity();
00153   SUNDANCE_MSG2(verb, tab0 
00154     << "ExplicitFunctionalDerivativeElement::internalFindW(order="
00155     << order << ") for " << toString());
00156 
00157 
00158   Set<MultipleDeriv> rtn ;
00159 
00160   if (order < 3)
00161   {
00162     Tabs tab1;
00163     const Set<MultipleDeriv>& WArgPlus 
00164       = evaluatableArg()->findW(order+1, context);
00165     
00166     SUNDANCE_MSG5(verb, tab1 << "WArgPlus = " << WArgPlus);
00167     MultipleDeriv me(fd_);
00168     Set<MultipleDeriv> WargPlusOslashFD = setDivision(WArgPlus, makeSet(me));
00169     SUNDANCE_MSG5(verb, tab1 << "WArgPlus / fd = " 
00170       << WargPlusOslashFD);
00171     rtn = WargPlusOslashFD;
00172   }
00173   SUNDANCE_MSG2(verb, tab0 << "W[" << order << "]=" << rtn);
00174   SUNDANCE_MSG2(verb, tab0 << "done with ExplicitFunctionalDerivativeElement::internalFindW(" << order << ") for "
00175                      << toString());
00176 
00177   return rtn;
00178 }
00179 
00180 
00181 Set<MultipleDeriv> ExplicitFunctionalDerivativeElement
00182 ::internalFindV(int order, const EvalContext& context) const
00183 {
00184   Tabs tabs(0);
00185   int verb = context.setupVerbosity();
00186   SUNDANCE_MSG2(verb, tabs << "ExplicitFunctionalDerivativeElement::internalFindV(" << order << ") for " 
00187                      << toString());
00188 
00189   Set<MultipleDeriv> rtn;
00190   
00191   {
00192     Tabs tab1;
00193     SUNDANCE_MSG5(verb, tab1 << "finding R");
00194     const Set<MultipleDeriv>& R = findR(order, context);
00195     SUNDANCE_MSG5(verb, tab1 << "finding C");
00196     const Set<MultipleDeriv>& C = findC(order, context);
00197     rtn = R.setDifference(C);
00198   }
00199   SUNDANCE_MSG2(verb, tabs << "V[" << order << "]=" << rtn);
00200   SUNDANCE_MSG2(verb, tabs << "done with ExplicitFunctionalDerivativeElement::internalFindV(" << order << ") for "
00201     << toString());
00202   
00203   return rtn;
00204 }
00205 
00206 
00207 Set<MultipleDeriv> ExplicitFunctionalDerivativeElement
00208 ::internalFindC(int order, const EvalContext& context) const
00209 {
00210   Tabs tabs(0);
00211   int verb = context.setupVerbosity();
00212   SUNDANCE_MSG2(verb, tabs << "ExplicitFunctionalDerivativeElement::internalFindC() for " 
00213     << toString());
00214   Set<MultipleDeriv> rtn ;
00215   if (order < 3) 
00216   {
00217     Tabs tab1;
00218     SUNDANCE_MSG5(verb, tab1 << "finding R");
00219     const Set<MultipleDeriv>& R = findR(order, context);
00220     SUNDANCE_MSG5(verb, tab1 << "R=" << R);
00221 
00222     SUNDANCE_MSG5(verb, tab1 << "finding C for arg");
00223     const Set<MultipleDeriv>& argC 
00224       = evaluatableArg()->findC(order+1, context);
00225     SUNDANCE_MSG5(verb, tab1 << "argC=" << argC);
00226 
00227     MultipleDeriv me(fd_);
00228     Set<MultipleDeriv> tmp = setDivision(argC, makeSet(me));
00229     rtn = tmp.intersection(R);
00230   }
00231 
00232   SUNDANCE_MSG2(verb, tabs << "C[" << order << "]=" << rtn);
00233   SUNDANCE_MSG2(verb, tabs << "done with ExplicitFunctionalDerivativeElement::internalFindC for "
00234     << toString());
00235   return rtn;
00236 }
00237 
00238 
00239 
00240 
00241 bool ExplicitFunctionalDerivativeElement
00242 ::lessThan(const ScalarExpr* other) const
00243 {
00244   const ExplicitFunctionalDerivativeElement* e 
00245     = dynamic_cast<const ExplicitFunctionalDerivativeElement*>(other);
00246   TEUCHOS_TEST_FOR_EXCEPTION(e==0, std::logic_error, "cast should never fail at this point");
00247   
00248   if (fd_ < e->fd_) return true;
00249   if (e->fd_ < fd_) return false;
00250   
00251   return ExprWithChildren::lessThan(other);
00252 }
00253 

Site Contact