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