void updateDiscreteFunction(const Expr& newVals, Expr old) { const DiscreteFunction* in = DiscreteFunction::discFunc(newVals); TEST_FOR_EXCEPT(in==0); DiscreteFunction* out = DiscreteFunction::discFunc(old); TEST_FOR_EXCEPT(out==0); Vector<double> vec = in->getVector(); out->setVector(vec); }
double FunctionalEvaluator::fdGradientCheck(double h) const { bool showAll = false; Tabs tabs; double f0, fPlus, fMinus; Expr gradF0 = evalGradient(f0); FancyOStream& os = Out::os(); DiscreteFunction* df = DiscreteFunction::discFunc(varValues_); DiscreteFunction* dg = DiscreteFunction::discFunc(gradF0); Vector<double> x = df->getVector(); Vector<double> x0 = x.copy(); Vector<double> gf = dg->getVector(); RCP<GhostView<double> > xView = df->ghostView(); RCP<GhostView<double> > gradF0View = dg->ghostView(); TEUCHOS_TEST_FOR_EXCEPTION(xView.get() == 0, std::runtime_error, "bad pointer in FunctionalEvaluator::fdGradientCheck"); TEUCHOS_TEST_FOR_EXCEPTION(gradF0View.get() == 0, std::runtime_error, "bad pointer in FunctionalEvaluator::fdGradientCheck"); int nTot = x.space().dim(); int n = x.space().numLocalElements(); int lowestIndex = x.space().baseGlobalNaturalIndex(); os << tabs << "doing fd check: h=" << h << std::endl; Array<double> df_dx(n); int localIndex = 0; for (int globalIndex=0; globalIndex<nTot; globalIndex++) { double tmp=0.0; bool isLocal = globalIndex >= lowestIndex && globalIndex < (lowestIndex+n); if (isLocal) { tmp = xView->getElement(globalIndex); loadable(x)->setElement(globalIndex, tmp + h); } df->setVector(x); fPlus = evaluate(); if (isLocal) { loadable(x)->setElement(globalIndex, tmp - h); } df->setVector(x); fMinus = evaluate(); if (isLocal) { df_dx[localIndex] = (fPlus - fMinus)/2.0/h; os << "g=" << setw(5) << globalIndex << ", l=" << setw(5) << localIndex << " f0=" << setw(12) << f0 << " fPlus=" << setw(12) << fPlus << " fMinus=" << setw(12) << fMinus << " df_dx=" << setw(12) << df_dx[localIndex] << std::endl; if (showAll) { os << "i " << globalIndex << " x_i=" << tmp << " f(x)=" << f0 << " f(x+h)=" << fPlus << " f(x-h)=" << fMinus << std::endl; } loadable(x)->setElement(globalIndex, tmp); localIndex++; } df->setVector(x); } double localMaxErr = 0.0; showAll = true; VectorSpace<double> space = x.space(); for (int i=0; i<space.numLocalElements(); i++) { double num = fabs(df_dx[i]-gf[i]); double den = fabs(df_dx[i]) + fabs(gf[i]) + 1.0e-14; double r = 0.0; if (fabs(den) > 1.0e-16) r = num/den; else r = 1.0; if (showAll) { os << "i " << i; os << " FD=" << df_dx[i] << " grad=" << gf[i] << " r=" << r << std::endl; } if (localMaxErr < r) localMaxErr = r; } os << "local max error = " << localMaxErr << std::endl; double maxErr = localMaxErr; df->mesh().comm().allReduce((void*) &localMaxErr, (void*) &maxErr, 1, MPIDataType::doubleType(), MPIOp::maxOp()); os << tabs << "fd check: max error = " << maxErr << std::endl; return maxErr; }