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 "SundanceSubtypeEvaluator.hpp"
00032 #include "SundanceEvalManager.hpp"
00033 #include "SundanceCoordExpr.hpp"
00034 #include "PlayaExceptions.hpp"
00035 #include "SundanceSet.hpp"
00036 #include "PlayaTabs.hpp"
00037 #include "SundanceOut.hpp"
00038 
00039 using namespace Sundance;
00040 using namespace Sundance;
00041 
00042 using namespace Sundance;
00043 using namespace Teuchos;
00044 
00045 
00046 CoordExprEvaluator::CoordExprEvaluator(const CoordExpr* expr, 
00047                                        const EvalContext& context)
00048   : SubtypeEvaluator<CoordExpr>(expr, context), 
00049     doValue_(false),
00050     doDeriv_(false),
00051     stringRep_(expr->toString())
00052 {
00053   int verb = context.setupVerbosity();
00054   Tabs tabs;
00055   SUNDANCE_MSG1(verb, tabs << "initializing coord expr evaluator for " 
00056                     << expr->toString());
00057   SUNDANCE_MSG2(verb, tabs << "return sparsity " << std::endl << tabs << *(this->sparsity)());
00058 
00059   TEUCHOS_TEST_FOR_EXCEPTION(this->sparsity()->numDerivs() > 2, std::logic_error,
00060                      "CoordExprEvaluator ctor found a sparsity table "
00061                      "with more than two entries. The bad sparsity table is "
00062                      << *(this->sparsity)());
00063 
00064   
00065 
00066 
00067 
00068 
00069   
00070   for (int i=0; i<this->sparsity()->numDerivs(); i++)
00071     {
00072       const MultipleDeriv& d = this->sparsity()->deriv(i);
00073 
00074       
00075       if (d.order()==0) 
00076         {
00077           doValue_ = true;
00078           addVectorIndex(i, 0);
00079         }
00080       else 
00081 
00082         {
00083           TEUCHOS_TEST_FOR_EXCEPTION(!this->sparsity()->isSpatialDeriv(i), std::logic_error,
00084                              "CoordExprEvaluator ctor found an entry in the "
00085                              "sparsity superset that is not a spatial derivative. "
00086                              "The bad entry is " << this->sparsity()->deriv(i) 
00087                              << ". The superset is " 
00088                              << *(this->sparsity)());
00089 
00090           const MultiIndex& mi = this->sparsity()->multiIndex(i);
00091           
00092           TEUCHOS_TEST_FOR_EXCEPTION(mi.order() != 1, std::logic_error,
00093                              "CoordExprEvaluator ctor found a multiindex of "
00094                              "order != 1. Bad multiindex is " << mi.toString());
00095           
00096           TEUCHOS_TEST_FOR_EXCEPTION(mi[expr->dir()]!=1, std::logic_error,
00097                              "CoordExprEvaluator sparsity pattern has an "
00098                              "element corresponding to differentiation wrt "
00099                              "a coordinate direction other than that of the "
00100                              "coord expr's direction");
00101           doDeriv_ = true;
00102           addConstantIndex(i, 0);
00103         }
00104     }
00105   
00106 }
00107 
00108 
00109 
00110 void CoordExprEvaluator::internalEval(const EvalManager& mgr,
00111   Array<double>& constantResults,
00112   Array<RCP<EvalVector> >& vectorResults) const 
00113 {
00114   Tabs tabs(0);
00115 
00116   SUNDANCE_MSG1(mgr.verb(), tabs << "CoordExprEvaluator::eval() expr=" << expr()->toString());
00117 
00118   SUNDANCE_MSG2(mgr.verb(), tabs << "sparsity = " << std::endl 
00119     << *(this->sparsity)())
00120 
00121   if (doValue_)
00122     {
00123       Tabs tab2;
00124       SUNDANCE_MSG3(mgr.verb(), tab2 << "computing value");
00125       vectorResults.resize(1);
00126       vectorResults[0] = mgr.popVector();
00127       mgr.evalCoordExpr(expr(), vectorResults[0]);
00128       mgr.stack().setVecSize(vectorResults[0]->length());
00129       vectorResults[0]->setString(stringRep_);
00130     }
00131   
00132   if (doDeriv_)
00133     {
00134       Tabs tab2;
00135       SUNDANCE_MSG3(mgr.verb(), tab2 << "computing derivative");
00136       constantResults.resize(1);
00137       constantResults[0] = 1.0;
00138     }
00139 
00140   if (mgr.verb() > 1)
00141     {
00142       Tabs tab1;
00143       Out::os() << tab1 << "results " << std::endl;
00144       mgr.showResults(Out::os(), this->sparsity(), vectorResults,
00145                             constantResults);
00146     }
00147 
00148 }
00149