NOX::Abstract::Group::ReturnType LOCA::TurningPoint::MinimallyAugmented::Constraint:: computeDP(const std::vector<int>& paramIDs, NOX::Abstract::MultiVector::DenseMatrix& dgdp, bool isValidG) { std::string callingFunction = "LOCA::TurningPoint::MinimallyAugmented::Constraint::computeDP()"; NOX::Abstract::Group::ReturnType status; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; // Compute sigma, w and v if necessary if (!isValidConstraints) { status = computeConstraints(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } // Compute -(w^T*J*v)_p status = grpPtr->computeDwtJnDp(paramIDs, (*w_vector)[0], (*v_vector)[0], dgdp, false); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); dgdp.scale(-1.0/sigma_scale); // Set the first column of dgdp dgdp(0,0) = constraints(0,0); return finalStatus; }
NOX::Abstract::Group::ReturnType LOCA::Hopf::MinimallyAugmented::Constraint:: computeDOmega(NOX::Abstract::MultiVector::DenseMatrix& domega) { string callingFunction = "LOCA::Hopf::MinimallyAugmented::Constraint::computeDOmega()"; NOX::Abstract::Group::ReturnType status; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; // Compute sigma, w and v if necessary if (!isValidConstraints) { status = computeConstraints(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } // Compute mass matrix M status = grpPtr->computeShiftedMatrix(0.0, 1.0); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute M*v Teuchos::RCP<NOX::Abstract::MultiVector> tmp_vector = v_vector->clone(NOX::ShapeCopy); status = grpPtr->applyShiftedMatrixMultiVector(*v_vector, *tmp_vector); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute u^T*M*v NOX::Abstract::MultiVector::DenseMatrix tmp_mat(2,2); tmp_vector->multiply(1.0, *w_vector, tmp_mat); // Compute domega domega(0,0) = tmp_mat(0,1) - tmp_mat(1,0); domega(1,0) = -(tmp_mat(0,0) + tmp_mat(1,1)); domega.scale(1.0/sigma_scale); return finalStatus; }
NOX::Abstract::Group::ReturnType LOCA::Hopf::MinimallyAugmented::Constraint:: computeDP(const vector<int>& paramIDs, NOX::Abstract::MultiVector::DenseMatrix& dgdp, bool isValidG) { string callingFunction = "LOCA::Hopf::MinimallyAugmented::Constraint::computeDP()"; NOX::Abstract::Group::ReturnType status; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; // Compute sigma, w and v if necessary if (!isValidConstraints) { status = computeConstraints(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } // Compute -(w^T*J*v)_p NOX::Abstract::MultiVector::DenseMatrix dgdp_real(Teuchos::View, dgdp, 1, paramIDs.size()+1, 0, 0); NOX::Abstract::MultiVector::DenseMatrix dgdp_imag(Teuchos::View, dgdp, 1, paramIDs.size()+1, 1, 0); status = grpPtr->computeDwtCeDp(paramIDs, (*w_vector)[0], (*w_vector)[1], (*v_vector)[0], (*v_vector)[1], omega, dgdp_real, dgdp_imag, false); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); dgdp.scale(-1.0/sigma_scale); // Set the first column of dgdp dgdp(0,0) = constraints(0,0); dgdp(1,0) = constraints(1,0); return finalStatus; }
// Solves Hopf equations via classic Salinger bordering // The first m columns of input_x, input_y, input_z store the RHS, the // next column stores df/dp, (Jy-wBz)_p and (Jz+wBy)_p respectively, the // last column of input_y and input_z store Bz and -By respectively. Note // input_x has m+1 columns, input_y and input_z have m+2, and input_w and // input_p have m columns. result_x, result_y, result_z, result_w and // result_param have the same dimensions as their input counterparts NOX::Abstract::Group::ReturnType LOCA::Hopf::MooreSpence::SalingerBordering::solveContiguous( Teuchos::ParameterList& params, const NOX::Abstract::MultiVector& input_x, const NOX::Abstract::MultiVector& input_y, const NOX::Abstract::MultiVector& input_z, const NOX::Abstract::MultiVector::DenseMatrix& input_w, const NOX::Abstract::MultiVector::DenseMatrix& input_p, NOX::Abstract::MultiVector& result_x, NOX::Abstract::MultiVector& result_y, NOX::Abstract::MultiVector& result_z, NOX::Abstract::MultiVector::DenseMatrix& result_w, NOX::Abstract::MultiVector::DenseMatrix& result_p) const { std::string callingFunction = "LOCA::Hopf::MooreSpence::SalingerBordering::solveContiguous()"; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; NOX::Abstract::Group::ReturnType status; int m = input_x.numVectors()-1; std::vector<int> index_input(m); std::vector<int> index_dp(1); std::vector<int> index_B(1); std::vector<int> index_ip(m+1); for (int i=0; i<m; i++) { index_input[i] = i; index_ip[i] = i; } index_ip[m] = m; index_dp[0] = m; index_B[0] = m+1; // verify underlying Jacobian is valid if (!group->isJacobian()) { status = group->computeJacobian(); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } // compute [A b] = J^-1 [F df/dp] status = group->applyJacobianInverseMultiVector(params, input_x, result_x); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); Teuchos::RCP<NOX::Abstract::MultiVector> A = result_x.subView(index_input); Teuchos::RCP<NOX::Abstract::MultiVector> b = result_x.subView(index_dp); // verify underlying complex matrix is valid if (!group->isComplex()) { status = group->computeComplex(w); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } // compute (J+iwB)(y+iz)_x [A b] Teuchos::RCP<NOX::Abstract::MultiVector> tmp_real = result_y.clone(NOX::ShapeCopy); Teuchos::RCP<NOX::Abstract::MultiVector> tmp_real_sub = tmp_real->subView(index_ip); Teuchos::RCP<NOX::Abstract::MultiVector> tmp_imag = result_y.clone(NOX::ShapeCopy); Teuchos::RCP<NOX::Abstract::MultiVector> tmp_imag_sub = tmp_imag->subView(index_ip); tmp_real->init(0.0); tmp_imag->init(0.0); status = group->computeDCeDxa(*yVector, *zVector, w, result_x, *CeRealVector, *CeImagVector, *tmp_real_sub, *tmp_imag_sub); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // compute [G+iH d(J+iwB)(y+iz)/dp iB(y+iz)] - [(J+iwB)_x[A b] 0+i0] tmp_real->update(1.0, input_y, -1.0); tmp_imag->update(1.0, input_z, -1.0); // verify underlying complex matrix is valid if (!group->isComplex()) { status = group->computeComplex(w); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } // compute [C+iD e+if g+ih] = (J+iwB)^-1 (tmp_real + i tmp_imag) status = group->applyComplexInverseMultiVector(params, *tmp_real, *tmp_imag, result_y, result_z); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); Teuchos::RCP<NOX::Abstract::MultiVector> C = result_y.subView(index_input); Teuchos::RCP<NOX::Abstract::MultiVector> D = result_z.subView(index_input); Teuchos::RCP<NOX::Abstract::MultiVector> e = result_y.subView(index_dp); Teuchos::RCP<NOX::Abstract::MultiVector> f = result_z.subView(index_dp); Teuchos::RCP<NOX::Abstract::MultiVector> g = result_y.subView(index_B); Teuchos::RCP<NOX::Abstract::MultiVector> h = result_z.subView(index_B); // compute lambda = ((phi^T h)(phi^T C-u) - (phi^T g)(phi^T D-v)) / // ((phi^T h)(phi^T e)-(phi^T g)(phi^T f)) NOX::Abstract::MultiVector::DenseMatrix ltC(1,m); NOX::Abstract::MultiVector::DenseMatrix ltD(1,m); double lte = hopfGroup->lTransNorm((*e)[0]); double ltf = hopfGroup->lTransNorm((*f)[0]); double ltg = hopfGroup->lTransNorm((*g)[0]); double lth = hopfGroup->lTransNorm((*h)[0]); double denom = lth*lte - ltg*ltf; hopfGroup->lTransNorm(*C, ltC); ltC -= input_w; ltC.scale(lth); hopfGroup->lTransNorm(*D, ltD); ltD -= input_p; result_p.assign(ltD); result_p.scale(-ltg); result_p += ltC; result_p.scale(1.0/denom); // compute omega = (phi^T D-v - (phi^T f)lambda)/(phi^T h) result_w.assign(result_p); result_w.scale(-ltf); result_w += ltD; result_w.scale(1.0/lth); // compute A = A - b*lambda (remember A is a sub-view of result_x) A->update(Teuchos::NO_TRANS, -1.0, *b, result_p, 1.0); // compute C = C - e*lambda - g*omega (remember C is a sub-view of result_y) C->update(Teuchos::NO_TRANS, -1.0, *e, result_p, 1.0); C->update(Teuchos::NO_TRANS, -1.0, *g, result_w, 1.0); // compute D = D - f*lambda - h*omega (remember D is a sub-view of result_z) D->update(Teuchos::NO_TRANS, -1.0, *f, result_p, 1.0); D->update(Teuchos::NO_TRANS, -1.0, *h, result_w, 1.0); return finalStatus; }