double FiniteDifferenceUtilities::finiteDifferenceGradient(MeshPtr mesh, RieszRepPtr residual, TSolutionPtr<double> backgroundSoln, int dofIndex) { residual->computeRieszRep(); double fx = residual->getNorm(); TSolutionPtr<double> solnPerturbation = TestingUtilities::makeNullSolution(mesh); // create perturbation in direction du solnPerturbation->clear(); // clear all solns TestingUtilities::initializeSolnCoeffs(solnPerturbation); TestingUtilities::setSolnCoeffForGlobalDofIndex(solnPerturbation,1.0,dofIndex); double h = 1e-7; backgroundSoln->addSolution(solnPerturbation,h); residual->computeRieszRep(); double fxh = residual->getNorm(); // get 1/2 squared norm (cost function) for each quantity double f = fx*fx*.5; double fh = fxh*fxh*.5; double fd_gradient = (fh-f)/h; // remove contribution backgroundSoln->addSolution(solnPerturbation,-h); return fd_gradient; }