NOX::Abstract::Group::ReturnType LOCA::DerivUtils::computeDwtJnDx(LOCA::MultiContinuation::AbstractGroup& grp, const NOX::Abstract::MultiVector& w, const NOX::Abstract::Vector& nullVector, NOX::Abstract::MultiVector& result) const { string callingFunction = "LOCA::DerivUtils::computeDwtJnDx()"; NOX::Abstract::Group::ReturnType status, finalStatus; // Vector to store w^T*J Teuchos::RCP<NOX::Abstract::MultiVector> wtJ = w.clone(NOX::ShapeCopy); // Compute base w^T*J finalStatus = grp.computeJacobian(); globalData->locaErrorCheck->checkReturnType(finalStatus, callingFunction); status = grp.applyJacobianTransposeMultiVector(w, *wtJ); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Copy original solution vector Teuchos::RCP<NOX::Abstract::Vector> Xvec = grp.getX().clone(NOX::DeepCopy); // Perturb solution vector in direction of nullVector, return perturbation double eps = perturbXVec(grp, *Xvec, nullVector); // Fill perturbed w^T*J vector finalStatus = grp.computeJacobian(); globalData->locaErrorCheck->checkReturnType(finalStatus, callingFunction); status = grp.applyJacobianTransposeMultiVector(w, result); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Difference perturbed and base vector result.update(-1.0, *wtJ, 1.0); result.scale(1.0/eps); // Restore original solution vector grp.setX(*Xvec); return finalStatus; }
double LOCA::DerivUtils::perturbXVec(LOCA::MultiContinuation::AbstractGroup& grp, const NOX::Abstract::Vector& xVector, const NOX::Abstract::Vector& aVector) const { // Allocate tempertory xVector Teuchos::RCP<NOX::Abstract::Vector> tmpXVecPtr = xVector.clone(NOX::DeepCopy); // Get perturbation size for directional derivative double eps = epsVector(*tmpXVecPtr, aVector); // Perturb temp vector and copy into group's x vector grp.setX(tmpXVecPtr->update(eps, aVector, 1.0)); // Return perturbation size return eps; }
NOX::Abstract::Group::ReturnType LOCA::DerivUtils::computeDJnDxa(LOCA::MultiContinuation::AbstractGroup& grp, const NOX::Abstract::Vector& nullVector, const NOX::Abstract::MultiVector& aVector, const NOX::Abstract::Vector& JnVector, NOX::Abstract::MultiVector& result) const { string callingFunction = "LOCA::DerivUtils::computeDJnDxa()"; NOX::Abstract::Group::ReturnType status, finalStatus; // Copy original solution vector Teuchos::RCP<NOX::Abstract::Vector> Xvec = grp.getX().clone(NOX::DeepCopy); // Loop over each column of multivector for (int i=0; i<aVector.numVectors(); i++) { // Perturb solution vector in direction of aVector, return perturbation double eps = perturbXVec(grp, *Xvec, aVector[i]); // Fill perturbed Jn vector finalStatus = grp.computeJacobian(); globalData->locaErrorCheck->checkReturnType(finalStatus, callingFunction); status = grp.applyJacobian(nullVector, result[i]); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Difference perturbed and base vector result[i].update(-1.0, JnVector, 1.0); result[i].scale(1.0/eps); } // Restore original solution vector grp.setX(*Xvec); return finalStatus; }