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 }