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 "SundanceCoordExpr.hpp"
00034 #include "PlayaExceptions.hpp"
00035 #include "SundanceSet.hpp"
00036 #include "PlayaTabs.hpp"
00037 #include "SundanceOut.hpp"
00038
00039 using namespace Sundance;
00040 using namespace Sundance;
00041
00042 using namespace Sundance;
00043 using namespace Teuchos;
00044
00045
00046 CoordExprEvaluator::CoordExprEvaluator(const CoordExpr* expr,
00047 const EvalContext& context)
00048 : SubtypeEvaluator<CoordExpr>(expr, context),
00049 doValue_(false),
00050 doDeriv_(false),
00051 stringRep_(expr->toString())
00052 {
00053 int verb = context.setupVerbosity();
00054 Tabs tabs;
00055 SUNDANCE_MSG1(verb, tabs << "initializing coord expr evaluator for "
00056 << expr->toString());
00057 SUNDANCE_MSG2(verb, tabs << "return sparsity " << std::endl << tabs << *(this->sparsity)());
00058
00059 TEUCHOS_TEST_FOR_EXCEPTION(this->sparsity()->numDerivs() > 2, std::logic_error,
00060 "CoordExprEvaluator ctor found a sparsity table "
00061 "with more than two entries. The bad sparsity table is "
00062 << *(this->sparsity)());
00063
00064
00065
00066
00067
00068
00069
00070 for (int i=0; i<this->sparsity()->numDerivs(); i++)
00071 {
00072 const MultipleDeriv& d = this->sparsity()->deriv(i);
00073
00074
00075 if (d.order()==0)
00076 {
00077 doValue_ = true;
00078 addVectorIndex(i, 0);
00079 }
00080 else
00081
00082 {
00083 TEUCHOS_TEST_FOR_EXCEPTION(!this->sparsity()->isSpatialDeriv(i), std::logic_error,
00084 "CoordExprEvaluator ctor found an entry in the "
00085 "sparsity superset that is not a spatial derivative. "
00086 "The bad entry is " << this->sparsity()->deriv(i)
00087 << ". The superset is "
00088 << *(this->sparsity)());
00089
00090 const MultiIndex& mi = this->sparsity()->multiIndex(i);
00091
00092 TEUCHOS_TEST_FOR_EXCEPTION(mi.order() != 1, std::logic_error,
00093 "CoordExprEvaluator ctor found a multiindex of "
00094 "order != 1. Bad multiindex is " << mi.toString());
00095
00096 TEUCHOS_TEST_FOR_EXCEPTION(mi[expr->dir()]!=1, std::logic_error,
00097 "CoordExprEvaluator sparsity pattern has an "
00098 "element corresponding to differentiation wrt "
00099 "a coordinate direction other than that of the "
00100 "coord expr's direction");
00101 doDeriv_ = true;
00102 addConstantIndex(i, 0);
00103 }
00104 }
00105
00106 }
00107
00108
00109
00110 void CoordExprEvaluator::internalEval(const EvalManager& mgr,
00111 Array<double>& constantResults,
00112 Array<RCP<EvalVector> >& vectorResults) const
00113 {
00114 Tabs tabs(0);
00115
00116 SUNDANCE_MSG1(mgr.verb(), tabs << "CoordExprEvaluator::eval() expr=" << expr()->toString());
00117
00118 SUNDANCE_MSG2(mgr.verb(), tabs << "sparsity = " << std::endl
00119 << *(this->sparsity)())
00120
00121 if (doValue_)
00122 {
00123 Tabs tab2;
00124 SUNDANCE_MSG3(mgr.verb(), tab2 << "computing value");
00125 vectorResults.resize(1);
00126 vectorResults[0] = mgr.popVector();
00127 mgr.evalCoordExpr(expr(), vectorResults[0]);
00128 mgr.stack().setVecSize(vectorResults[0]->length());
00129 vectorResults[0]->setString(stringRep_);
00130 }
00131
00132 if (doDeriv_)
00133 {
00134 Tabs tab2;
00135 SUNDANCE_MSG3(mgr.verb(), tab2 << "computing derivative");
00136 constantResults.resize(1);
00137 constantResults[0] = 1.0;
00138 }
00139
00140 if (mgr.verb() > 1)
00141 {
00142 Tabs tab1;
00143 Out::os() << tab1 << "results " << std::endl;
00144 mgr.showResults(Out::os(), this->sparsity(), vectorResults,
00145 constantResults);
00146 }
00147
00148 }
00149