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 "SundanceSymbolicFuncEvaluator.hpp"
00034 #include "SundanceDiscreteFuncEvaluator.hpp"
00035 #include "SundanceConstantEvaluator.hpp"
00036 #include "SundanceSymbolicFuncElement.hpp"
00037 #include "SundanceDiscreteFuncElement.hpp"
00038 #include "SundanceParameter.hpp"
00039 #include "SundanceZeroExpr.hpp"
00040 #include "SundanceSet.hpp"
00041 #include "PlayaTabs.hpp"
00042 #include "SundanceOut.hpp"
00043 
00044 using namespace Sundance;
00045 using namespace Sundance;
00046 
00047 using namespace Sundance;
00048 using namespace Teuchos;
00049 
00050 
00051 
00052 SymbolicFuncElementEvaluator
00053 ::SymbolicFuncElementEvaluator(const SymbolicFuncElement* expr, 
00054   const EvalContext& context)
00055   : SubtypeEvaluator<SymbolicFuncElement>(expr, context),
00056     mi_(),
00057     spatialDerivPtrs_(),
00058     onePtrs_(),
00059     paramValuePtrs_(),
00060     df_(dynamic_cast<const DiscreteFuncElement*>(expr->evalPt())),
00061     p_(dynamic_cast<const Parameter*>(expr->evalPt())),
00062     dfEval_(0),
00063     pEval_(0),
00064     stringReps_()
00065 {
00066   
00067   Tabs tabs;
00068   int verb = context.evalSetupVerbosity();
00069 
00070   SUNDANCE_MSG1(verb, tabs << "initializing symbolic func evaluator for " 
00071     << expr->toString());
00072 
00073   SUNDANCE_MSG2(verb, tabs << "return sparsity " << std::endl << *(this->sparsity)());
00074 
00075   const ZeroExpr* z 
00076     = dynamic_cast<const ZeroExpr*>(expr->evalPt());
00077   
00078   TEUCHOS_TEST_FOR_EXCEPTION(z==0 && df_==0, std::logic_error,
00079     "SymbolicFuncElementEvaluator ctor detected an "
00080     "evaluation point=" << expr->toString()
00081     << " that is neither zero nor a discrete "
00082     "function.");
00083 
00084 
00085   static Array<string> coordNames;
00086   if (coordNames.size() != 3)
00087   {
00088     coordNames.resize(3);
00089     coordNames[0] = "x";
00090     coordNames[1] = "y";
00091     coordNames[2] = "z";
00092   }
00093   
00094   int constantCounter = 0;
00095   int vectorCounter = 0;
00096 
00097   Set<MultiIndex> miSet;
00098   
00099   for (int i=0; i<this->sparsity()->numDerivs(); i++) 
00100   {
00101     if (this->sparsity()->isSpatialDeriv(i))
00102     {
00103       
00104       TEUCHOS_TEST_FOR_EXCEPTION(z != 0, std::logic_error,
00105         "SymbolicFuncElementEvaluator ctor detected a "
00106         "spatial derivative of a zero function. All "
00107         "such expressions should have been "
00108         "automatically eliminated by this point.");
00109       TEUCHOS_TEST_FOR_EXCEPTION(p_ != 0, std::logic_error,
00110         "SymbolicFuncElementEvaluator ctor detected a "
00111         "spatial derivative of a constant parameter. All "
00112         "such expressions should have been "
00113         "automatically eliminated by this point.");
00114 
00115       mi_.append(this->sparsity()->multiIndex(i));
00116       miSet.put(this->sparsity()->multiIndex(i));
00117       addVectorIndex(i, vectorCounter);
00118       spatialDerivPtrs_.append(vectorCounter++);
00119       int dir = this->sparsity()->multiIndex(i).firstOrderDirection();
00120       string deriv = "D[" + df_->name() + ", " + coordNames[dir] + "]";
00121       stringReps_.append(deriv);
00122     }
00123     else
00124     {
00125       TEUCHOS_TEST_FOR_EXCEPTION(this->sparsity()->deriv(i).order() > 1,
00126         std::logic_error,
00127         "SymbolicFuncElementEvaluator ctor detected a "
00128         "nonzero functional derivative of order greater "
00129         "than one. All such derivs should have been "
00130         "identified as zero by this point. The bad "
00131         "derivative is " << this->sparsity()->deriv(i)
00132         << ", and the bad sparsity table is "
00133         << *(this->sparsity)());
00134 
00135       if (this->sparsity()->deriv(i).order()==0)
00136       {
00137         TEUCHOS_TEST_FOR_EXCEPTION(z != 0, std::logic_error,
00138           "SymbolicFuncElementEvaluator ctor detected a "
00139           "zero-order derivative of a zero function. All "
00140           "such expressions should have been "
00141           "automatically eliminated by this point.");
00142         
00143 
00144         if (p_ == 0)
00145         {
00146           addVectorIndex(i, vectorCounter);
00147           spatialDerivPtrs_.append(vectorCounter++);
00148         }
00149         else
00150         {
00151           addConstantIndex(i, constantCounter);
00152           paramValuePtrs_.append(constantCounter++);
00153         }
00154         mi_.append(MultiIndex());
00155         miSet.put(MultiIndex());
00156         stringReps_.append(df_->name());
00157       }
00158       else
00159       {
00160         
00161         addConstantIndex(i, constantCounter);
00162         onePtrs_.append(constantCounter++);
00163       }
00164     }
00165   }
00166 
00167   if (p_==0 && df_ != 0)
00168   {
00169     SUNDANCE_MSG2(verb, tabs << "setting up evaluation for discrete eval pt");
00170     df_->setupEval(context);
00171     dfEval_ = dynamic_cast<const DiscreteFuncElementEvaluator*>(df_->evaluator(context).get());
00172   }
00173   else if (p_ != 0)
00174   {
00175     SUNDANCE_MSG2(verb, tabs << "setting up evaluation for parameter eval pt");
00176     p_->setupEval(context);
00177     pEval_ = dynamic_cast<const ConstantEvaluator*>(p_->evaluator(context).get());
00178   }
00179 }
00180 
00181 
00182 
00183 
00184 void SymbolicFuncElementEvaluator
00185 ::internalEval(const EvalManager& mgr,
00186   Array<double>& constantResults,
00187   Array<RCP<EvalVector> >& vectorResults) const 
00188 {
00189   Tabs tabs;
00190   
00191   SUNDANCE_MSG1(mgr.verb(), 
00192     tabs << "SymbolicFuncElementEvaluator::eval: expr=" 
00193     << expr()->toString());
00194   SUNDANCE_MSG2(mgr.verb(), tabs << "sparsity = " 
00195     << std::endl << *(this->sparsity)());
00196 
00197   constantResults.resize(onePtrs_.size() + paramValuePtrs_.size());
00198   vectorResults.resize(spatialDerivPtrs_.size());
00199 
00200   
00201   if (p_==0 && df_ != 0 && mi_.size() > 0)
00202   {
00203     for (int i=0; i<mi_.size(); i++)
00204     {
00205       vectorResults[i] = mgr.popVector();
00206       TEUCHOS_TEST_FOR_EXCEPTION(!vectorResults[i]->isValid(), 
00207         std::logic_error,
00208         "invalid evaluation vector allocated in "
00209         "SymbolicFuncElementEvaluator::internalEval()");
00210       vectorResults[i]->setString(stringReps_[i]);
00211     }
00212     mgr.evalDiscreteFuncElement(df_, mi_, vectorResults);
00213     mgr.stack().setVecSize(vectorResults[0]->length());
00214   }
00215   if (p_!=0 && mi_.size() > 0)
00216   {
00217     Array<RCP<EvalVector> > paramVectorResults;
00218     Array<double> paramConstResults;
00219     pEval_->eval(mgr, paramConstResults, paramVectorResults);
00220     constantResults[paramValuePtrs_[0]] = paramConstResults[0];
00221   }
00222 
00223   
00224   for (int i=0; i<onePtrs_.size(); i++)
00225   {
00226     constantResults[onePtrs_[i]] = 1.0;
00227   }
00228   if (verb() > 2)
00229   {
00230     Out::os() << tabs << "results " << std::endl;
00231     this->sparsity()->print(Out::os(), vectorResults,
00232       constantResults);
00233   }
00234   SUNDANCE_MSG1(mgr.verb(), tabs << "SymbolicFuncEvaluator::eval() done"); 
00235 
00236 }
00237 
00238 
00239 void SymbolicFuncElementEvaluator::resetNumCalls() const
00240 {
00241   if (pEval_) pEval_->resetNumCalls();
00242   if (dfEval_) dfEval_->resetNumCalls();
00243   Evaluator::resetNumCalls();
00244 }