NOX::Abstract::Group::ReturnType LOCA::DerivUtils::computeDfDp(LOCA::MultiContinuation::AbstractGroup& grp, const vector<int>& param_ids, NOX::Abstract::MultiVector& result, bool isValidF) const { string callingFunction = "LOCA::DerivUtils::computeDfDp()"; NOX::Abstract::Group::ReturnType status, finalStatus; // Views of f, df/dp NOX::Abstract::Vector *f = &result[0]; NOX::Abstract::Vector *dfdp = NULL; // Compute base residual F if (!isValidF) { finalStatus = grp.computeF(); globalData->locaErrorCheck->checkReturnType(finalStatus, callingFunction); *f = grp.getF(); } else finalStatus = NOX::Abstract::Group::Ok; double param; double eps; // Loop over each parameter for (unsigned int i=0; i<param_ids.size(); i++) { // Perturb single parameter in this group, and return perturbation, eps eps = perturbParam(grp, param, param_ids[i]); // Compute perturbed residual status = grp.computeF(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Difference perturbed and base vector dfdp = &result[i+1]; dfdp->update(1.0, grp.getF(), -1.0, *f, 0.0); dfdp->scale(1.0/eps); // Restore original parameter value grp.setParam(param_ids[i], param); } return finalStatus; }
double LOCA::DerivUtils::perturbParam(LOCA::MultiContinuation::AbstractGroup& grp, double& paramOrig, int param_id) const { paramOrig = grp.getParam(param_id); // Find perturbation size and perturb parameter double eps = epsScalar(paramOrig); double param = paramOrig + eps; // Copy this perturbed parameter vector into group grp.setParam(param_id, param); // Return perturbation size return eps; }
NOX::Abstract::Group::ReturnType LOCA::DerivUtils::computeDwtJDp(LOCA::MultiContinuation::AbstractGroup& grp, const vector<int>& paramIDs, const NOX::Abstract::Vector& w, NOX::Abstract::MultiVector& result, bool isValid) const { string callingFunction = "LOCA::DerivUtils::computeDwtJDp()"; NOX::Abstract::Group::ReturnType status, finalStatus; // Views of w^T*J, d(w^T*J)/dp NOX::Abstract::Vector *wtJ = &result[0]; NOX::Abstract::Vector *dwtJdp = NULL; // Compute base residual w^T*J if (!isValid) { finalStatus = grp.computeJacobian(); globalData->locaErrorCheck->checkReturnType(finalStatus, callingFunction); status = grp.applyJacobianTranspose(w, *wtJ); 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 w^T*J vector status = grp.computeJacobian(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); dwtJdp = &result[i+1]; status = grp.applyJacobianTranspose(w, *dwtJdp); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Difference perturbed and base vector dwtJdp->update(-1.0, *wtJ, 1.0); dwtJdp->scale(1.0/eps); // Restore original parameter value grp.setParam(paramIDs[i], param); } 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; }