SundanceSymbolicFuncEvaluator.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 "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       /* evaluate the spatial deriv applied to the evaluation point */
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         /* value of zeroth functional deriv is either 
00143          * a discrete function or a parameter */
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         /* value of first functional deriv is one */
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   /* Evaluate discrete functions if necessary */
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   /* Set the known one entries to one */
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 }

Site Contact