void Rotate_002( ) { vector_type eX( 1, 0, 0 ); vector_type eY( 0, 1, 0 ); quaternion_type q = quaternion_type::rotate( eX, eY ); vector_type _eX = q.rotate( eY ); CPPUNIT_ASSERTION_DOUBLES_EQUAL( _eX.x, value_type( -1 ), 1.0e-6 ); CPPUNIT_ASSERTION_DOUBLES_EQUAL( _eX.y, value_type( 0 ), 1.0e-6 ); CPPUNIT_ASSERTION_DOUBLES_EQUAL( _eX.z, value_type( 0 ), 1.0e-6 ); }
int EpetraOperator::ApplyInverse(const Epetra_MultiVector& X, Epetra_MultiVector& Y) const { try { // There is no rcpFromRef(const T&), so we need to do const_cast const Xpetra::EpetraMultiVector eX(rcpFromRef(const_cast<Epetra_MultiVector&>(X))); Xpetra::EpetraMultiVector eY(rcpFromRef(Y)); // Generally, we assume two different vectors, but AztecOO uses a single vector if (X.Values() == Y.Values()) { // X and Y point to the same memory, use an additional vector RCP<Xpetra::EpetraMultiVector> tmpY = Teuchos::rcp(new Xpetra::EpetraMultiVector(eY.getMap(), eY.getNumVectors())); // InitialGuessIsZero in MueLu::Hierarchy.Iterate() does not zero out components, it // only assumes that user provided an already zeroed out vector bool initialGuessZero = true; tmpY->putScalar(0.0); // apply one V-cycle as preconditioner Hierarchy_->Iterate(eX, 1, *tmpY, initialGuessZero); // deep copy solution from MueLu eY.update(1.0, *tmpY, 0.0); } else { // X and Y point to different memory, pass the vectors through // InitialGuessIsZero in MueLu::Hierarchy.Iterate() does not zero out components, it // only assumes that user provided an already zeroed out vector bool initialGuessZero = true; eY.putScalar(0.0); Hierarchy_->Iterate(eX, 1, eY, initialGuessZero); } } catch (std::exception& e) { //TODO: error msg directly on std::cerr? std::cerr << "Caught an exception in MueLu::EpetraOperator::ApplyInverse():" << std::endl << e.what() << std::endl; return -1; } return 0; }