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

Site Contact