void LOCA::AnasaziOperator::Cayley2Matrix::apply(const NOX::Abstract::MultiVector& input, NOX::Abstract::MultiVector& output) const { std::string callingFunction = "LOCA::AnasaziOperator::Cayley2Matrix::apply()"; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; NOX::Abstract::Group::ReturnType status; // Allocate temporary vector if (tmp_r == Teuchos::null || tmp_r->numVectors() != input.numVectors()) tmp_r = input.clone(NOX::ShapeCopy); // Compute J-mu*M -- moved to preProcessSeedVector // Compute (J-mu*M)*input status = grp->applySecondShiftedMatrixMultiVector(input, *tmp_r); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute J-sigma*M -- moved to preProcessSeedVector // Solve (J-sigma*M)*output = (J-mu*M)*input status = grp->applyShiftedMatrixInverseMultiVector(*solverParams, *tmp_r, output); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); }
LOCA::MultiContinuation::ExtendedMultiVector::ExtendedMultiVector( const Teuchos::RCP<LOCA::GlobalData>& global_data, const NOX::Abstract::MultiVector& xVec, int nScalarRows) : LOCA::Extended::MultiVector(global_data, xVec.numVectors(), 1, nScalarRows) { LOCA::Extended::MultiVector::setMultiVectorPtr(0, xVec.clone(NOX::DeepCopy)); }
void LOCA::Epetra::AnasaziOperator::Floquet::apply(const NOX::Abstract::MultiVector& input, NOX::Abstract::MultiVector& output) const { // Apply first part of monodromy operator on input vector Teuchos::RCP<NOX::Abstract::MultiVector> tmpVec = input.clone(); for (int i=0; i < input.numVectors(); i++) { NOX::Abstract::Vector& nAV = tmpVec->operator[](i); NOX::Epetra::Vector& nEV = dynamic_cast<NOX::Epetra::Vector&>(nAV); Epetra_Vector& eV = nEV.getEpetraVector(); xyztInterface->beginFloquetOperatorApplication(eV); } // Now apply the main part of the monodromy matrix NOX::Abstract::Group::ReturnType status = grp->applyJacobianInverseMultiVector(*solverParams, *(tmpVec.get()), output); globalData->locaErrorCheck->checkReturnType(status, "LOCA::Epetra::AnasaziOperator::Floquet::apply()"); for (int i=0; i < input.numVectors(); i++) { NOX::Abstract::Vector& nAV = output.operator[](i); NOX::Epetra::Vector& nEV = dynamic_cast<NOX::Epetra::Vector&>(nAV); Epetra_Vector& eV = nEV.getEpetraVector(); xyztInterface->finishFloquetOperatorApplication(eV); } // Was this needed? // TESTING: Doubling the call to this routine resulted in the // squaring of the Floquet multipliers, as they should. // Replacing the apply function so the operator is diagonal // with entries 1/(i+2) led to the Floquet multipliers. /* std::cout << " Fixing apply so Floquets at 1/2 1/3 1/4 ... " << std::endl; Teuchos::RCP<NOX::Abstract::MultiVector> tmpVec = input.clone(); for (int i=0; i < input.numVectors(); i++) { NOX::Abstract::Vector& nAV = output.operator[](i); NOX::Epetra::Vector& nEV = dynamic_cast<NOX::Epetra::Vector&>(nAV); Epetra_Vector& oV = nEV.getEpetraVector(); NOX::Abstract::Vector& nAV2 = tmpVec->operator[](i); NOX::Epetra::Vector& nEV2 = dynamic_cast<NOX::Epetra::Vector&>(nAV2); Epetra_Vector& iV = nEV2.getEpetraVector(); for (int j=0; j < iV.MyLength(); j++) { oV[j] = iV[j] / (j + 2.0); } } */ }
LOCA::MultiContinuation::ExtendedMultiVector::ExtendedMultiVector( const Teuchos::RCP<LOCA::GlobalData>& global_data, const NOX::Abstract::MultiVector& xVec, const NOX::Abstract::MultiVector::DenseMatrix& params) : LOCA::Extended::MultiVector(global_data, xVec.numVectors(), 1, params.numRows()) { LOCA::Extended::MultiVector::setMultiVectorPtr(0, xVec.clone(NOX::DeepCopy)); LOCA::Extended::MultiVector::getScalars()->assign(params); }
NOX::Abstract::Group::ReturnType LOCA::BorderedSolver::Nested::applyInverseTranspose( Teuchos::ParameterList& params, const NOX::Abstract::MultiVector* F, const NOX::Abstract::MultiVector::DenseMatrix* G, NOX::Abstract::MultiVector& X, NOX::Abstract::MultiVector::DenseMatrix& Y) const { bool isZeroF = (F == NULL); bool isZeroG = (G == NULL); if (isZeroF && isZeroG) { X.init(0.0); Y.putScalar(0.0); } int num_cols = X.numVectors(); Teuchos::RCP<NOX::Abstract::MultiVector> FF; if (!isZeroF) FF = unbordered_grp->getX().createMultiVector(num_cols); NOX::Abstract::MultiVector::DenseMatrix GG(myWidth, num_cols); GG.putScalar(0.0); if (!isZeroF) { NOX::Abstract::MultiVector::DenseMatrix GG1(Teuchos::View, GG, underlyingWidth, num_cols, 0, 0); grp->extractSolutionComponent(*F, *FF); grp->extractParameterComponent(false, *F, GG1); } if (!isZeroG) { NOX::Abstract::MultiVector::DenseMatrix GG2(Teuchos::View, GG, numConstraints, num_cols, underlyingWidth, 0); GG2.assign(*G); } Teuchos::RCP<NOX::Abstract::MultiVector> XX = unbordered_grp->getX().createMultiVector(num_cols); NOX::Abstract::MultiVector::DenseMatrix YY(myWidth, num_cols); NOX::Abstract::MultiVector::DenseMatrix YY1(Teuchos::View, YY, underlyingWidth, num_cols, 0, 0); NOX::Abstract::MultiVector::DenseMatrix YY2(Teuchos::View, YY, numConstraints, num_cols, underlyingWidth, 0); NOX::Abstract::Group::ReturnType status = solver->applyInverseTranspose(params, FF.get(), &GG, *XX, YY); Y.assign(YY2); grp->loadNestedComponents(*XX, YY1, X); return status; }
void LOCA::MultiContinuation::ConstrainedGroup::fillB( NOX::Abstract::MultiVector& B) const { std::string callingFunction = "LOCA::MultiContinuation::ConstrainedGroup::fillB"; bool isZeroB = constraintsPtr->isDXZero(); Teuchos::RCP<const NOX::Abstract::MultiVector> my_B; if (!isZeroB) { Teuchos::RCP<const LOCA::MultiContinuation::ConstraintInterfaceMVDX> constraints_mvdx = Teuchos::rcp_dynamic_cast<const LOCA::MultiContinuation::ConstraintInterfaceMVDX>(constraintsPtr); if (constraints_mvdx == Teuchos::null) globalData->locaErrorCheck->throwError( callingFunction, std::string("Constraints object must be of type") + std::string("ConstraintInterfaceMVDX")); my_B = Teuchos::rcp(constraints_mvdx->getDX(),false); } // If the underlying system isn't bordered, we're done if (!isBordered) { if (isZeroB) B.init(0.0); else B = *my_B; return; } // Create views for underlying group int w = bordered_grp->getBorderedWidth(); std::vector<int> idx1(w); for (int i=0; i<w; i++) idx1[i] = i; Teuchos::RCP<NOX::Abstract::MultiVector> underlyingB = B.subView(idx1); // Combine blocks in underlying group bordered_grp->fillB(*underlyingB); // Create views for my blocks std::vector<int> idx2(numParams); for (int i=0; i<numParams; i++) idx2[i] = w+i; Teuchos::RCP<NOX::Abstract::MultiVector> my_B_x = B.subView(idx2); // Extract solution component from my_B and store in B if (isZeroB) my_B_x->init(0.0); else bordered_grp->extractSolutionComponent(*my_B, *my_B_x); }
NOX::Abstract::Group::ReturnType LOCA::Epetra::ModelEvaluatorInterface:: computeDfDp(LOCA::MultiContinuation::AbstractGroup& grp, const vector<int>& param_ids, NOX::Abstract::MultiVector& result, bool isValidF) const { // Break result into f and df/dp NOX::Epetra::Vector& f = dynamic_cast<NOX::Epetra::Vector&>(result[0]); Epetra_Vector& epetra_f = f.getEpetraVector(); std::vector<int> dfdp_index(result.numVectors()-1); for (unsigned int i=0; i<dfdp_index.size(); i++) dfdp_index[i] = i+1; Teuchos::RefCountPtr<NOX::Epetra::MultiVector> dfdp = Teuchos::rcp_dynamic_cast<NOX::Epetra::MultiVector>(result.subView(dfdp_index)); Epetra_MultiVector& epetra_dfdp = dfdp->getEpetraMultiVector(); // Create inargs EpetraExt::ModelEvaluator::InArgs inargs = model_->createInArgs(); const NOX::Epetra::Vector& x = dynamic_cast<const NOX::Epetra::Vector&>(grp.getX()); const Epetra_Vector& epetra_x = x.getEpetraVector(); inargs.set_x(Teuchos::rcp(&epetra_x, false)); inargs.set_p(0, Teuchos::rcp(¶m_vec, false)); if (inargs.supports(EpetraExt::ModelEvaluator::IN_ARG_x_dot)) { // Create x_dot, filled with zeros if (x_dot == NULL) x_dot = new Epetra_Vector(epetra_x.Map()); inargs.set_x_dot(Teuchos::rcp(x_dot, false)); } // Create outargs EpetraExt::ModelEvaluator::OutArgs outargs = model_->createOutArgs(); if (!isValidF) { EpetraExt::ModelEvaluator::Evaluation<Epetra_Vector> eval_f; Teuchos::RefCountPtr<Epetra_Vector> F = Teuchos::rcp(&epetra_f, false); eval_f.reset(F, EpetraExt::ModelEvaluator::EVAL_TYPE_EXACT); outargs.set_f(eval_f); } Teuchos::RefCountPtr<Epetra_MultiVector> DfDp = Teuchos::rcp(&epetra_dfdp, false); Teuchos::Array<int> param_indexes(param_ids.size()); for (unsigned int i=0; i<param_ids.size(); i++) param_indexes[i] = param_ids[i]; EpetraExt::ModelEvaluator::DerivativeMultiVector dmv(DfDp, EpetraExt::ModelEvaluator::DERIV_MV_BY_COL, param_indexes); EpetraExt::ModelEvaluator::Derivative deriv(dmv); outargs.set_DfDp(0, deriv); model_->evalModel(inargs, outargs); return NOX::Abstract::Group::Ok; }
NOX::Abstract::Group::ReturnType LOCA::Epetra::Group::applyComplexMultiVector( const NOX::Abstract::MultiVector& input_real, const NOX::Abstract::MultiVector& input_imag, NOX::Abstract::MultiVector& result_real, NOX::Abstract::MultiVector& result_imag) const { std::string callingFunction = "LOCA::Epetra::Group::applyComplexMultiVector()"; // We must have the time-dependent interface if (userInterfaceTime == Teuchos::null) return NOX::Abstract::Group::BadDependency; #ifdef HAVE_NOX_EPETRAEXT const NOX::Epetra::MultiVector& epetra_input_real = dynamic_cast<const NOX::Epetra::MultiVector&>(input_real); const NOX::Epetra::MultiVector& epetra_input_imag = dynamic_cast<const NOX::Epetra::MultiVector&>(input_imag); NOX::Epetra::MultiVector& epetra_result_real = dynamic_cast<NOX::Epetra::MultiVector&>(result_real); NOX::Epetra::MultiVector& epetra_result_imag = dynamic_cast<NOX::Epetra::MultiVector&>(result_imag); // Get Jacobian matrix for row map Teuchos::RCP<Epetra_RowMatrix> jac = Teuchos::rcp_dynamic_cast<Epetra_RowMatrix>(sharedLinearSystem.getObject(this)->getJacobianOperator()); EpetraExt::BlockMultiVector complex_input(jac->RowMatrixRowMap(), complexMatrix->RowMap(), input_real.numVectors()); complex_input.LoadBlockValues(epetra_input_real.getEpetraMultiVector(), 0); complex_input.LoadBlockValues(epetra_input_imag.getEpetraMultiVector(), 1); EpetraExt::BlockMultiVector complex_result(jac->RowMatrixRowMap(), complexMatrix->RowMap(), input_real.numVectors()); complex_result.PutScalar(0.0); complexMatrix->Apply(complex_input, complex_result); complex_result.ExtractBlockValues(epetra_result_real.getEpetraMultiVector(), 0); complex_result.ExtractBlockValues(epetra_result_imag.getEpetraMultiVector(), 1); return NOX::Abstract::Group::Ok; #else globalData->locaErrorCheck->throwError(callingFunction, "Must have EpetraExt support for Hopf tracking. Configure trilinos with --enable-epetraext"); return NOX::Abstract::Group::BadDependency; #endif }
LOCA::TurningPoint::MooreSpence::ExtendedMultiVector::ExtendedMultiVector( const Teuchos::RCP<LOCA::GlobalData>& global_data, const NOX::Abstract::MultiVector& xVec, const NOX::Abstract::MultiVector& nullVec, const NOX::Abstract::MultiVector::DenseMatrix& bifParams) : LOCA::Extended::MultiVector(global_data, xVec.numVectors(), 2, 1) { LOCA::Extended::MultiVector::setMultiVectorPtr(0, xVec.clone(NOX::DeepCopy)); LOCA::Extended::MultiVector::setMultiVectorPtr(1, nullVec.clone(NOX::DeepCopy)); LOCA::Extended::MultiVector::getScalars()->assign(bifParams); }
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; }
LOCA::Hopf::MooreSpence::ExtendedMultiVector::ExtendedMultiVector( const Teuchos::RCP<LOCA::GlobalData>& global_data, const NOX::Abstract::MultiVector& xVec, const NOX::Abstract::MultiVector& realEigenVec, const NOX::Abstract::MultiVector& imagEigenVec, const NOX::Abstract::MultiVector::DenseMatrix& freqs, const NOX::Abstract::MultiVector::DenseMatrix& bifParams) : LOCA::Extended::MultiVector(global_data, xVec.numVectors(), 3, 2) { LOCA::Extended::MultiVector::setMultiVectorPtr(0, xVec.clone(NOX::DeepCopy)); LOCA::Extended::MultiVector::setMultiVectorPtr(1, realEigenVec.clone(NOX::DeepCopy)); LOCA::Extended::MultiVector::setMultiVectorPtr(2, imagEigenVec.clone(NOX::DeepCopy)); LOCA::Extended::MultiVector::getScalarRows(1,0)->assign(freqs); LOCA::Extended::MultiVector::getScalarRows(1,1)->assign(bifParams); }
LOCA::Pitchfork::MooreSpence::ExtendedMultiVector::ExtendedMultiVector( const Teuchos::RCP<LOCA::GlobalData>& global_data, const NOX::Abstract::MultiVector& xVec, const NOX::Abstract::MultiVector& nullVec, const NOX::Abstract::MultiVector::DenseMatrix& slacks, const NOX::Abstract::MultiVector::DenseMatrix& bifParams) : LOCA::Extended::MultiVector(global_data, xVec.numVectors(), 2, 2) { LOCA::Extended::MultiVector::setMultiVectorPtr(0, xVec.clone(NOX::DeepCopy)); LOCA::Extended::MultiVector::setMultiVectorPtr(1, nullVec.clone(NOX::DeepCopy)); LOCA::Extended::MultiVector::getScalarRows(1,0)->assign(slacks); LOCA::Extended::MultiVector::getScalarRows(1,1)->assign(bifParams); }
NOX::Abstract::Group::ReturnType LOCA::LAPACK::Group::applyShiftedMatrixInverseMultiVector( Teuchos::ParameterList& params, const NOX::Abstract::MultiVector& input, NOX::Abstract::MultiVector& result) const { // Number of RHS int nVecs = input.numVectors(); int m = shiftedSolver.getMatrix().numRows(); // Copy all input vectors into one matrix NOX::LAPACK::Matrix<double> B(m,nVecs); const NOX::LAPACK::Vector* constVecPtr; for (int j=0; j<nVecs; j++) { constVecPtr = dynamic_cast<const NOX::LAPACK::Vector*>(&(input[j])); for (int i=0; i<m; i++) B(i,j) = (*constVecPtr)(i); } bool res = shiftedSolver.solve(false, nVecs, &B(0,0)); if (!res) return NOX::Abstract::Group::Failed; // Copy result from matrix NOX::LAPACK::Vector* vecPtr; for (int j=0; j<nVecs; j++) { vecPtr = dynamic_cast<NOX::LAPACK::Vector*>(&(result[j])); for (int i=0; i<m; i++) (*vecPtr)(i) = B(i,j); } return NOX::Abstract::Group::Ok; }
NOX::Abstract::Group::ReturnType LOCA::LAPACK::Group::applyShiftedMatrixMultiVector( const NOX::Abstract::MultiVector& input, NOX::Abstract::MultiVector& result) const { // Number of RHS int nVecs = input.numVectors(); int m = shiftedSolver.getMatrix().numRows(); // Copy all input vectors into one matrix NOX::LAPACK::Matrix<double> B(m,nVecs); NOX::LAPACK::Matrix<double> C(m,nVecs); const NOX::LAPACK::Vector* constVecPtr; for (int j=0; j<nVecs; j++) { constVecPtr = dynamic_cast<const NOX::LAPACK::Vector*>(&(input[j])); for (int i=0; i<m; i++) B(i,j) = (*constVecPtr)(i); } // Apply shifted matrix shiftedSolver.apply(false, nVecs, &B(0,0), &C(0,0)); // Copy result from matrix NOX::LAPACK::Vector* vecPtr; for (int j=0; j<nVecs; j++) { vecPtr = dynamic_cast<NOX::LAPACK::Vector*>(&(result[j])); for (int i=0; i<m; i++) (*vecPtr)(i) = C(i,j); } return NOX::Abstract::Group::Ok; }
void LOCA::TurningPoint::MooreSpence::ExtendedGroup::lTransNorm( const NOX::Abstract::MultiVector& n, NOX::Abstract::MultiVector::DenseMatrix& result) const { n.multiply(1.0 / lengthVec->length(), *lengthMultiVec, result); }
void LOCA::AnasaziOperator::Cayley2Matrix::preProcessSeedVector(NOX::Abstract::MultiVector& ivec) { // Changes random seed vector ivec: ivec = (J - sigma*M)^{-1}*M*ivec std::string callingFunction = "LOCA::AnasaziOperator::Cayley2Matrix::preProcessSeedVector()"; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; NOX::Abstract::Group::ReturnType status; // Allocate temporary vector if (tmp_r == Teuchos::null || tmp_r->numVectors() != ivec.numVectors()) tmp_r = ivec.clone(NOX::ShapeCopy); // Compute M status = grp->computeShiftedMatrix(0.0, 1.0); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute M*ivec status = grp->applyShiftedMatrixMultiVector(ivec, *tmp_r); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute J-sigma*M status = grp->computeShiftedMatrix(1.0, -sigma); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Solve (J-sigma*M)*output = (M)*ivec status = grp->applyShiftedMatrixInverseMultiVector(*solverParams, *tmp_r, ivec); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute J-mu*M status = grp->computeSecondShiftedMatrix(1.0, -mu); }
NOX::Abstract::Group::ReturnType LOCA::MultiContinuation::ConstraintInterfaceMVDX::addDX( Teuchos::ETransp transb, double alpha, const NOX::Abstract::MultiVector::DenseMatrix& b, double beta, NOX::Abstract::MultiVector& result_x) const { if (!isDXZero()) { const NOX::Abstract::MultiVector* dgdx = getDX(); result_x.update(transb, alpha, *dgdx, b, beta); } else result_x.scale(beta); return NOX::Abstract::Group::Ok; }
NOX::Abstract::Group::ReturnType LOCA::LAPACK::Group::applyComplexTransposeInverseMultiVector( Teuchos::ParameterList& params, const NOX::Abstract::MultiVector& input_real, const NOX::Abstract::MultiVector& input_imag, NOX::Abstract::MultiVector& result_real, NOX::Abstract::MultiVector& result_imag) const { #ifdef HAVE_TEUCHOS_COMPLEX // Check validity of the Jacobian if (!isComplex()) return NOX::Abstract::Group::BadDependency; int n = complexSolver.getMatrix().numRows(); int p = input_real.numVectors(); // Copy inputs into a complex vector std::vector< std::complex<double> > input(n*p); const NOX::LAPACK::Vector* lapack_input_real; const NOX::LAPACK::Vector* lapack_input_imag; for (int j=0; j<p; j++) { lapack_input_real = dynamic_cast<const NOX::LAPACK::Vector*>(&(input_real[j])); lapack_input_imag = dynamic_cast<const NOX::LAPACK::Vector*>(&(input_imag[j])); for (int i=0; i<n; i++) input[i+n*j] = std::complex<double>((*lapack_input_real)(i), (*lapack_input_imag)(i)); } // Solve complex matrix bool res = complexSolver.solve(true, p, &input[0]); // Copy result into NOX vectors NOX::LAPACK::Vector* lapack_result_real; NOX::LAPACK::Vector* lapack_result_imag; for (int j=0; j<p; j++) { lapack_result_real = dynamic_cast<NOX::LAPACK::Vector*>(&(result_real[j])); lapack_result_imag = dynamic_cast<NOX::LAPACK::Vector*>(&(result_imag[j])); for (int i=0; i<n; i++) { (*lapack_result_real)(i) = input[i+n*j].real(); (*lapack_result_imag)(i) = input[i+n*j].imag(); } } if (res) return NOX::Abstract::Group::Ok; else return NOX::Abstract::Group::Failed; #else globalData->locaErrorCheck->throwError( "LOCA::LAPACK::Group::applyComplexTransposeInverseMultiVector()", "TEUCHOS_COMPLEX must be enabled for complex support! Reconfigure with -D Teuchos_ENABLE_COMPLEX"); return NOX::Abstract::Group::BadDependency; #endif }
void LOCA::AnasaziOperator::ShiftInvert::apply( const NOX::Abstract::MultiVector& input, NOX::Abstract::MultiVector& output) const { std::string callingFunction = "LOCA::AnasaziOperator::ShiftInvert::apply()"; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; NOX::Abstract::Group::ReturnType status; // Allocate temporary vector if (tmp_r == Teuchos::null || tmp_r->numVectors() != input.numVectors()) tmp_r = input.clone(NOX::ShapeCopy); // Compute M status = grp->computeShiftedMatrix(0.0, 1.0); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute M*input status = grp->applyShiftedMatrixMultiVector(input, *tmp_r); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Compute J-omega*M status = grp->computeShiftedMatrix(1.0, -shift); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Solve (J-omega*M)*output = M*input status = grp->applyShiftedMatrixInverseMultiVector(*solverParams, *tmp_r, output); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); }
NOX::Abstract::Group::ReturnType LOCA::Epetra::Group::applyShiftedMatrixInverseMultiVector( Teuchos::ParameterList& lsParams, const NOX::Abstract::MultiVector& input, NOX::Abstract::MultiVector& result) const { if (shiftedSharedLinearSystem != Teuchos::null) { NOX::Epetra::LinearSystem::PreconditionerReusePolicyType precPolicy = sharedLinearSystem.getObject(this)->getPreconditionerPolicy(); if (!isValidShiftedPrec) { if (precPolicy == NOX::Epetra::LinearSystem::PRPT_REBUILD) { shiftedSharedLinearSystem->getObject(this)->destroyPreconditioner(); shiftedSharedLinearSystem->getObject(this)-> createPreconditioner(xVector, lsParams, false); isValidShiftedPrec = true; } else if (precPolicy == NOX::Epetra::LinearSystem::PRPT_RECOMPUTE) { sharedLinearSystem.getObject(this)->recomputePreconditioner(xVector, lsParams); } else if (precPolicy == NOX::Epetra::LinearSystem::PRPT_REUSE) { // Do Nothing!!! } } const NOX::Epetra::Vector* epetra_input; NOX::Epetra::Vector* epetra_result; bool status; bool finalStatus = true; for (int i=0; i<input.numVectors(); i++) { epetra_input = dynamic_cast<const NOX::Epetra::Vector*>(&input[i]); epetra_result = dynamic_cast<NOX::Epetra::Vector*>(&result[i]); status = shiftedSharedLinearSystem->getObject(this)->applyJacobianInverse( lsParams, *epetra_input, *epetra_result); finalStatus = finalStatus && status; } if (finalStatus) return NOX::Abstract::Group::Ok; else return NOX::Abstract::Group::NotConverged; } else return NOX::Abstract::Group::BadDependency; }
NOX::Abstract::Group::ReturnType LOCA::Epetra::Group::applyJacobianTransposeInverseMultiVector( Teuchos::ParameterList& params, const NOX::Abstract::MultiVector& input, NOX::Abstract::MultiVector& result) const { std::string callingFunction = "LOCA::Epetra::Group::applyJacobianTransposeInverseMultiVector()"; NOX::Abstract::Group::ReturnType status; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; // Get non-const linsys Teuchos::RCP<NOX::Epetra::LinearSystem> linSys = sharedLinearSystem.getObject(this); // Get Jacobian operator Teuchos::RCP<Epetra_Operator> jac = linSys->getJacobianOperator(); // Instantiate transpose solver LOCA::Epetra::TransposeLinearSystem::Factory tls_factory(globalData); if (tls_strategy == Teuchos::null) tls_strategy = tls_factory.create(Teuchos::rcp(¶ms, false), linSys); // Compute Jacobian transpose J^T tls_strategy->createJacobianTranspose(); // Now compute preconditioner for J^T tls_strategy->createTransposePreconditioner(xVector, params); // Solve for each RHS int m = input.numVectors(); for (int i=0; i<m; i++) { bool stat = tls_strategy->applyJacobianTransposeInverse( params, dynamic_cast<const NOX::Epetra::Vector&>(input[i]), dynamic_cast<NOX::Epetra::Vector&>(result[i])); if (stat == true) status = NOX::Abstract::Group::Ok; else status = NOX::Abstract::Group::NotConverged; finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); } // Set original operators in linear system jac->SetUseTranspose(false); linSys->setJacobianOperatorForSolve(jac); linSys->destroyPreconditioner(); return finalStatus; }
NOX::Abstract::Group::ReturnType LOCA::DerivUtils::computeDCeDxa( LOCA::Hopf::MooreSpence::AbstractGroup& grp, const NOX::Abstract::Vector& yVector, const NOX::Abstract::Vector& zVector, double w, const NOX::Abstract::MultiVector& aVector, const NOX::Abstract::Vector& Ce_real, const NOX::Abstract::Vector& Ce_imag, NOX::Abstract::MultiVector& result_real, NOX::Abstract::MultiVector& result_imag) const { string callingFunction = "LOCA::DerivUtils::computeDCeDxa()"; NOX::Abstract::Group::ReturnType status, finalStatus = NOX::Abstract::Group::Ok; // 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]); // Compute perturbed Ce vectors status = grp.computeComplex(w); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); status = grp.applyComplex(yVector, zVector, result_real[i], result_imag[i]); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Difference perturbed and base vector and return approximate derivative result_real[i].update(-1.0, Ce_real, 1.0); result_real[i].scale(1.0/eps); result_imag[i].update(-1.0, Ce_imag, 1.0); result_imag[i].scale(1.0/eps); } // Restore original solution vector grp.setX(*Xvec); return finalStatus; }
// ============================================================================= // Compute result_p = alpha * dg/dx * input_x. NOX::Abstract::Group::ReturnType Ginla::FDM::Constraint::MinDist:: multiplyDX ( double alpha, const NOX::Abstract::MultiVector & input_x, NOX::Abstract::MultiVector::DenseMatrix & result_p ) const { TEUCHOS_ASSERT( komplex_.is_valid_ptr() && !komplex_.is_null() ); TEUCHOS_ASSERT_EQUALITY( result_p.numCols(), input_x.numVectors() ); for ( int k=0; k<input_x.numVectors(); k++ ) { const Epetra_Vector & xE = Teuchos::dyn_cast<const NOX::Epetra::Vector>( input_x[0] ).getEpetraVector(); Teuchos::RCP<ComplexVector> xPsi = komplex_->real2complex( xE ); result_p(0,k) = alpha * std::imag( psiRef_->dot(*xPsi) ); } return NOX::Abstract::Group::Ok; }
void LOCA::BorderedSolver::HouseholderQR::applyHouseholderVector( const NOX::Abstract::MultiVector::DenseMatrix& V1, const NOX::Abstract::MultiVector& V2, double beta, NOX::Abstract::MultiVector::DenseMatrix& A1, NOX::Abstract::MultiVector& A2) { int nColsA = A2.numVectors(); // Compute u = V2^T * A2 NOX::Abstract::MultiVector::DenseMatrix u(1, nColsA); A2.multiply(1.0, V2, u); // Compute u = u + V1^T * A_P u.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, V1, A1, 1.0); // Compute A1 = A1 - b*V1*u A1.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, -beta, V1, u, 1.0); // Compute A2 = A2 - b*V2*u A2.update(Teuchos::NO_TRANS, -beta, V2, u, 1.0); }
NOX::Abstract::Group::ReturnType LOCA::Homotopy::DeflatedGroup:: applyJacobianTransposeMultiVector(const NOX::Abstract::MultiVector& input, NOX::Abstract::MultiVector& result) const { string callingFunction = "LOCA::Homotopy::DeflatedGroup::applyJacobianTransposeMultiVector()"; if (!isJacobian()) { globalData->locaErrorCheck->throwError(callingFunction, "Called with invalid Jacobian!"); } // Cast inputs to continuation multivectors const LOCA::MultiContinuation::ExtendedMultiVector& c_input = dynamic_cast<const LOCA::MultiContinuation::ExtendedMultiVector&>(input); LOCA::MultiContinuation::ExtendedMultiVector& c_result = dynamic_cast<LOCA::MultiContinuation::ExtendedMultiVector&>(result); // Get x, param componenets of input vector Teuchos::RCP<const NOX::Abstract::MultiVector> input_x = c_input.getXMultiVec(); Teuchos::RCP<const NOX::Abstract::MultiVector::DenseMatrix> input_param = c_input.getScalars(); // Get references to x, param components of result vector Teuchos::RCP<NOX::Abstract::MultiVector> result_x = c_result.getXMultiVec(); Teuchos::RCP<NOX::Abstract::MultiVector::DenseMatrix> result_param = c_result.getScalars(); NOX::Abstract::Group::ReturnType status = grpPtr->applyJacobianTransposeMultiVector(*input_x, *result_x); // If the Jacobian is not augmented for homotopy (i.e. using MFNK) // then lets augment it here. if (augmentJacForHomotopyNotImplemented) result_x->update(1.0-conParam, *input_x, conParam/distProd); // Add deflated terms if (numSolns > 0) { NOX::Abstract::MultiVector::DenseMatrix tmp(1, input.numVectors()); input_x->multiply(1.0, *underlyingF, tmp); result_x->update(Teuchos::NO_TRANS, 1.0, *totalDistMultiVec, tmp, 1.0); } // Zero out parameter component result_param->putScalar(0.0); return status; }
void LOCA::Homotopy::DeflatedGroup:: fillA(NOX::Abstract::MultiVector& A) const { string callingFunction = "LOCA::Homotopy::DeflatedGroup::fillA"; Teuchos::RCP<const NOX::Abstract::MultiVector> my_A = underlyingF; // If the underlying system isn't bordered, we're done if (!isBordered) { A = *my_A; return; } // Create views for underlying group int w = bordered_grp->getBorderedWidth(); std::vector<int> idx1(w); for (int i=0; i<w; i++) idx1[i] = i; Teuchos::RCP<NOX::Abstract::MultiVector> underlyingA = A.subView(idx1); // Fill A block in underlying group bordered_grp->fillA(*underlyingA); // Create views for my blocks std::vector<int> idx2(1); for (int i=0; i<1; i++) idx2[i] = w+i; Teuchos::RCP<NOX::Abstract::MultiVector> my_A_x = A.subView(idx2); // Extract solution component from my_A and store in A bordered_grp->extractSolutionComponent(*my_A, *my_A_x); }
void LOCA::Homotopy::DeflatedGroup:: fillB(NOX::Abstract::MultiVector& B) const { string callingFunction = "LOCA::Homotopy::DeflatedGroup::fillB"; Teuchos::RCP<const NOX::Abstract::MultiVector> my_B = totalDistMultiVec; // If the underlying system isn't bordered, we're done if (!isBordered) { B = *my_B; return; } // Create views for underlying group int w = bordered_grp->getBorderedWidth(); std::vector<int> idx1(w); for (int i=0; i<w; i++) idx1[i] = i; Teuchos::RCP<NOX::Abstract::MultiVector> underlyingB = B.subView(idx1); // Combine blocks in underlying group bordered_grp->fillB(*underlyingB); // Create views for my blocks std::vector<int> idx2(2); for (int i=0; i<1; i++) idx2[i] = w+i; Teuchos::RCP<NOX::Abstract::MultiVector> my_B_x = B.subView(idx2); // Extract solution component from my_B and store in B bordered_grp->extractSolutionComponent(*my_B, *my_B_x); }
NOX::Abstract::Group::ReturnType LOCA::Pitchfork::MooreSpence::ExtendedGroup::computeDfDpMulti( const vector<int>& paramIDs, NOX::Abstract::MultiVector& dfdp, bool isValid_F) { string callingFunction = "LOCA::Pitchfork::MooreSpence::ExtendedGroup::computeDfDpMulti()"; NOX::Abstract::Group::ReturnType finalStatus = NOX::Abstract::Group::Ok; NOX::Abstract::Group::ReturnType status; // Cast dfdp to pitchfork vector LOCA::Pitchfork::MooreSpence::ExtendedMultiVector& pf_dfdp = dynamic_cast<LOCA::Pitchfork::MooreSpence::ExtendedMultiVector&>(dfdp); // Compute df/dp // Note: the first column of fMultiVec stores f + sigma*psi, not f, // so we always need to recompute f. This changes the first column // of fMultiVec back to f status = grpPtr->computeDfDpMulti(paramIDs, *pf_dfdp.getXMultiVec(), false); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Change the first column back to f + sigma*psi double sigma = xVec->getSlack(); pf_dfdp.getColumn(0)->getXVec()->update(sigma, *asymVec, 1.0); // Compute d(Jn)/dp status = grpPtr->computeDJnDpMulti(paramIDs, *(xVec->getNullVec()), *pf_dfdp.getNullMultiVec(), isValid_F); finalStatus = globalData->locaErrorCheck->combineAndCheckReturnTypes(status, finalStatus, callingFunction); // Set parameter components if (!isValid_F) { pf_dfdp.getScalar(0,0) = grpPtr->innerProduct(*(xVec->getXVec()), *asymVec); pf_dfdp.getScalar(1,0) = lTransNorm(*(xVec->getNullVec())); } for (int i=0; i<dfdp.numVectors()-1; i++) { pf_dfdp.getScalar(0,i+1) = 0.0; pf_dfdp.getScalar(1,i+1) = 0.0; } return finalStatus; }
void LOCA::BorderedSolver::HouseholderQR::applyCompactWY( const NOX::Abstract::MultiVector::DenseMatrix& Y1, const NOX::Abstract::MultiVector& Y2, const NOX::Abstract::MultiVector::DenseMatrix& T, NOX::Abstract::MultiVector::DenseMatrix& X1, NOX::Abstract::MultiVector& X2, bool isZeroX1, bool isZeroX2, bool useTranspose) const { if (isZeroX1 && isZeroX2) { X1.putScalar(0.0); X2.init(0.0); return; } int m = Y2.numVectors(); Teuchos::ETransp T_flag; if (useTranspose) T_flag = Teuchos::TRANS; else T_flag = Teuchos::NO_TRANS; NOX::Abstract::MultiVector::DenseMatrix tmp(m, X2.numVectors()); // Compute Y1^T*X1 + Y2^T*X2 if (!isZeroX2) X2.multiply(1.0, Y2, tmp); // Opportunity for optimization here since Y1 is a lower-triangular // matrix with unit diagonal if (!isZeroX2 && !isZeroX1) tmp.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, Y1, X1, 1.0); else if (!isZeroX1) tmp.multiply(Teuchos::TRANS, Teuchos::NO_TRANS, 1.0, Y1, X1, 0.0); // Compute op(T)*(Y1^T*X1 + Y2^T*X2) dblas.TRMM(Teuchos::LEFT_SIDE, Teuchos::UPPER_TRI, T_flag, Teuchos::NON_UNIT_DIAG, tmp.numRows(), tmp.numCols(), 1.0, T.values(), T.numRows(), tmp.values(), tmp.numRows()); // Compute X1 = X1 + Y1*op(T)*(Y1^T*X1 + Y2^T*X2) // Opportunity for optimization here since Y1 is a lower-triangular // matrix with unit diagonal if (isZeroX1) X1.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, Y1, tmp, 0.0); else X1.multiply(Teuchos::NO_TRANS, Teuchos::NO_TRANS, 1.0, Y1, tmp, 1.0); // Compute X2 = X2 + Y1*op(T)*(Y1^T*X1 + Y2^T*X2) if (isZeroX2) X2.update(Teuchos::NO_TRANS, 1.0, Y2, tmp, 0.0); else X2.update(Teuchos::NO_TRANS, 1.0, Y2, tmp, 1.0); }
NOX::Abstract::Group::ReturnType LOCA::Homotopy::Group::computeDfDpMulti(const vector<int>& paramIDs, NOX::Abstract::MultiVector& dfdp, bool isValidF) { // g = conParam * f(x) + ((1.0 - conParam) * (x - randomVec)) // dg/dp = f(x) - (x - randomVec) when p = conParam // dg/dp = conParam * df/dp when p != conParam // For simplicity, we always recompute g, even if isValidF is true // Things get kind of messy otherwise // Extract parameter IDs that are not the continuation parameter vector<int> pIDs; vector<int> idx(1); idx[0] = 0; // index 0 corrsponds to f in dfdp for (unsigned int i=0; i<paramIDs.size(); i++) if (paramIDs[i] != conParamID) { pIDs.push_back(paramIDs[i]); idx.push_back(i+1); } // Create view of dfdp for parameters that aren't the continuation parameter Teuchos::RCP<NOX::Abstract::MultiVector> fp = dfdp.subView(idx); // Compute df/dp for non-continuation parameter parameters // We force recomputation of f for simplicity NOX::Abstract::Group::ReturnType status = grpPtr->computeDfDpMulti(pIDs, *fp, false); // Compute conParam * df/dp fp->scale(conParam); // Compute g double v = 1.0-conParam; dfdp[0].update(v, grpPtr->getX(), -v, *randomVecPtr, 1.0); // Compute dg/dp for p = conParam grpPtr->computeF(); for (unsigned int i=0; i<paramIDs.size(); i++) if (paramIDs[i] == conParamID) { dfdp[i+1] = grpPtr->getF(); dfdp[i+1].update(-1.0, grpPtr->getX(), 1.0, *randomVecPtr, 1.0); } return status; }