SundanceDiscreteFuncEvaluator.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 "SundanceDiscreteFuncEvaluator.hpp"
00043 #include "SundanceEvalManager.hpp"
00044 #include "SundanceCoordExpr.hpp"
00045 #include "SundanceZeroExpr.hpp"
00046 #include "SundanceSpatiallyConstantExpr.hpp"
00047 #include "SundanceSymbolicFuncElement.hpp"
00048 #include "SundanceDiscreteFuncElement.hpp"
00049 #include "SundanceSet.hpp"
00050 #include "PlayaTabs.hpp"
00051 #include "SundanceOut.hpp"
00052 
00053 using namespace Sundance;
00054 using namespace Sundance;
00055 
00056 using namespace Sundance;
00057 using namespace Teuchos;
00058 
00059 
00060 
00061 DiscreteFuncElementEvaluator
00062 ::DiscreteFuncElementEvaluator(const DiscreteFuncElement* expr, 
00063                                const EvalContext& context)
00064   : SubtypeEvaluator<DiscreteFuncElement>(expr, context), 
00065     mi_(this->sparsity()->numDerivs()),
00066     miToIndexMap_(),
00067     stringReps_()
00068 {
00069   Tabs tabs;
00070   SUNDANCE_VERB_MEDIUM(tabs << "initializing discrete func evaluator for " 
00071                     << expr->toString());
00072 
00073   SUNDANCE_VERB_MEDIUM(tabs << "return sparsity " << std::endl << *(this->sparsity()));
00074 
00075   static Array<string> coordNames;
00076   if (coordNames.size() != 3)
00077     {
00078       coordNames.resize(3);
00079       coordNames[0] = "x";
00080       coordNames[1] = "y";
00081       coordNames[2] = "z";
00082     }
00083   std::string funcName = expr->name();
00084 
00085   for (int i=0; i<this->sparsity()->numDerivs(); i++)
00086     {
00087       /* Make sure that every derivative we're to evaluate is either
00088       * zero-order or a spatial derivative */
00089       if (this->sparsity()->deriv(i).order()==0) 
00090         {
00091           mi_[i] = MultiIndex();
00092         }
00093       else 
00094         {
00095       
00096           TEUCHOS_TEST_FOR_EXCEPTION(!this->sparsity()->isSpatialDeriv(i), std::logic_error,
00097                              "DiscreteFuncElementEvaluator ctor found "
00098                              "an entry in the sparsity superset that is not "
00099                              "a spatial derivative. "
00100                              "The bad entry is " << this->sparsity()->deriv(i) 
00101                              << ". The superset is " 
00102                              << *(this->sparsity)());
00103 
00104           mi_[i] = this->sparsity()->multiIndex(i);
00105         }
00106       addVectorIndex(i,i);
00107       TEUCHOS_TEST_FOR_EXCEPTION(miToIndexMap_.containsKey(mi_[i]), std::logic_error,
00108                          "DiscreteFuncElementEvaluator ctor detected a "
00109                          "duplicate multiindex");
00110 
00111       miToIndexMap_.put(mi_[i], i);
00112 
00113       if (mi_[i].order()==0)
00114         {
00115           stringReps_.append(funcName);
00116         }
00117       else
00118         {
00119           int dir = mi_[i].firstOrderDirection();
00120           std::string deriv = "D[" + funcName + ", " + coordNames[dir] + "]";
00121           stringReps_.append(deriv);
00122         }
00123     }
00124 
00125   
00126 }
00127 
00128 bool DiscreteFuncElementEvaluator::hasMultiIndex(const MultiIndex& mi) const
00129 {
00130   Tabs tabs;
00131   bool rtn = miToIndexMap_.containsKey(mi);
00132   SUNDANCE_VERB_MEDIUM(tabs << "checking for mi=" << mi << " for " 
00133                        << expr()->toString()
00134                        << std::endl << tabs 
00135                        << " sparsity " << std::endl << *(this->sparsity()));
00136   
00137   return rtn;
00138 }
00139 
00140 int DiscreteFuncElementEvaluator::miIndex(const MultiIndex& mi) const
00141 {
00142   return miToIndexMap_.get(mi);
00143 }
00144 
00145 
00146 void DiscreteFuncElementEvaluator
00147 ::internalEval(const EvalManager& mgr,
00148                Array<double>& constantResults,
00149                Array<RCP<EvalVector> >& vectorResults) const 
00150 {
00151   Tabs tabs(0);
00152   SUNDANCE_MSG1(mgr.verb(),
00153     tabs << "DiscreteFuncElementEvaluator::eval: expr=" 
00154     << expr()->toString());
00155 
00156   vectorResults.resize(mi_.size());
00157   for (int i=0; i<mi_.size(); i++)
00158     {
00159       Tabs tab2;
00160       vectorResults[i] = mgr.popVector();
00161       TEUCHOS_TEST_FOR_EXCEPTION(!vectorResults[i]->isValid(), 
00162                          std::logic_error,
00163                          "invalid evaluation vector allocated in "
00164                          "DiscreteFuncElementEvaluator::internalEval()");
00165       SUNDANCE_MSG2(mgr.verb(),tab2<< "setting string rep " << stringReps_[i]);
00166       vectorResults[i]->setString(stringReps_[i]);
00167     }
00168   mgr.evalDiscreteFuncElement(expr(), mi_, vectorResults);
00169   mgr.stack().setVecSize(vectorResults[0]->length());
00170   
00171   if (mgr.verb() > 1)
00172     {
00173       Out::os() << tabs << "results " << std::endl;
00174       mgr.showResults(Out::os(), sparsity(), vectorResults,
00175                             constantResults);
00176     }
00177   SUNDANCE_MSG1(mgr.verb(), tabs << "DiscreteFuncEvaluator::eval() done"); 
00178 }
00179 

Site Contact