NOX::Abstract::Group::ReturnType LOCA::DerivUtils::computeDJnDxa(LOCA::MultiContinuation::AbstractGroup& grp, const NOX::Abstract::Vector& nullVector, const NOX::Abstract::MultiVector& aVector, NOX::Abstract::MultiVector& result) const { string callingFunction = "LOCA::DerivUtils::computeDJnDxa()"; NOX::Abstract::Group::ReturnType status, finalStatus; // Allocate base Jn vector and fill with J times n Teuchos::RCP<NOX::Abstract::Vector> baseJnVectorPtr = nullVector.clone(NOX::ShapeCopy); if (!grp.isJacobian()) { finalStatus = grp.computeJacobian(); globalData->locaErrorCheck->checkReturnType(finalStatus, callingFunction); } else finalStatus = NOX::Abstract::Group::Ok; status = grp.applyJacobian(nullVector, *baseJnVectorPtr); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Now that Jn is known, call other routine status = computeDJnDxa(grp, nullVector, aVector, *baseJnVectorPtr, result); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); return finalStatus; }
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; }
NOX::Abstract::Group::ReturnType LOCA::DerivUtils::computeDwtJnDp( LOCA::MultiContinuation::AbstractGroup& grp, const vector<int>& paramIDs, const NOX::Abstract::Vector& w, const NOX::Abstract::Vector& nullVector, NOX::Abstract::MultiVector::DenseMatrix& result, bool isValid) const { string callingFunction = "LOCA::DerivUtils::computeDwtJnDp()"; NOX::Abstract::Group::ReturnType status, finalStatus; // Vector to store J*n Teuchos::RCP<NOX::Abstract::Vector> Jn = w.clone(NOX::ShapeCopy); double base_wtJn; // Compute base w^T*J*n if (!isValid) { // Compute J finalStatus = grp.computeJacobian(); globalData->locaErrorCheck->checkReturnType(finalStatus, callingFunction); // Compute J*n status = grp.applyJacobian(nullVector, *Jn); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute w^T*J*n base_wtJn = w.innerProduct(*Jn); result(0,0) = base_wtJn; } else { base_wtJn = result(0,0); finalStatus = NOX::Abstract::Group::Ok; } double param; double eps; double perturb_wtJn; // Loop over each parameter for (unsigned int i=0; i<paramIDs.size(); i++) { // Perturb single parameter in this group, and return perturbation, eps eps = perturbParam(grp, param, paramIDs[i]); // Compute perturbed J status = grp.computeJacobian(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute perturbed J*n status = grp.applyJacobian(nullVector, *Jn); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute perturbed w^T*J*n perturb_wtJn = w.innerProduct(*Jn); // Difference perturbed and base values result(0,i+1) = (perturb_wtJn - base_wtJn) / eps; // Restore original parameter value grp.setParam(paramIDs[i], param); } return finalStatus; }
NOX::Abstract::Group::ReturnType LOCA::DerivUtils::computeDJnDp(LOCA::MultiContinuation::AbstractGroup& grp, const vector<int>& paramIDs, const NOX::Abstract::Vector& nullVector, NOX::Abstract::MultiVector& result, bool isValid) const { string callingFunction = "LOCA::DerivUtils::computeDJnDp()"; NOX::Abstract::Group::ReturnType status, finalStatus; // Views of Jn, d(Jn)/dp NOX::Abstract::Vector *Jn = &result[0]; NOX::Abstract::Vector *dJndp = NULL; // Compute base residual if (!isValid) { finalStatus = grp.computeJacobian(); globalData->locaErrorCheck->checkReturnType(finalStatus, callingFunction); status = grp.applyJacobian(nullVector, *Jn); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } else finalStatus = NOX::Abstract::Group::Ok; double param; double eps; // Loop over each parameter for (unsigned int i=0; i<paramIDs.size(); i++) { // Perturb single parameter in this group, and return perturbation, eps eps = perturbParam(grp, param, paramIDs[i]); // Fill perturbed Jn vector status = grp.computeJacobian(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); dJndp = &result[i+1]; status = grp.applyJacobian(nullVector, *dJndp); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Difference perturbed and base vector dJndp->update(-1.0, *Jn, 1.0); dJndp->scale(1.0/eps); // Restore original parameter value grp.setParam(paramIDs[i], param); } return finalStatus; }