void GatherEigenvectors<EvalT,Traits>:: evaluateFields(typename Traits::EvalData workset) { if(nEigenvectors == 0) return; if(workset.eigenDataPtr->eigenvectorRe != Teuchos::null) { if(workset.eigenDataPtr->eigenvectorIm != Teuchos::null) { //Gather real and imaginary parts from workset Eigendata info structure const Epetra_MultiVector& e_r = *(workset.eigenDataPtr->eigenvectorRe); const Epetra_MultiVector& e_i = *(workset.eigenDataPtr->eigenvectorIm); int numVecsInWorkset = std::min(e_r.NumVectors(),e_i.NumVectors()); int numVecsToGather = std::min(numVecsInWorkset, (int)nEigenvectors); for (std::size_t cell=0; cell < workset.numCells; ++cell ) { const Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> >& nodeID = workset.wsElNodeEqID[cell]; for(std::size_t node =0; node < this->numNodes; ++node) { int offsetIntoVec = nodeID[node][0]; // neq==1 hardwired for (std::size_t k = 0; k < numVecsToGather; ++k) { (this->eigenvector_Re[k])(cell,node) = (*(e_r(k)))[offsetIntoVec]; (this->eigenvector_Im[k])(cell,node) = (*(e_i(k)))[offsetIntoVec]; } } } } else { // Only real parts of eigenvectors is given -- "gather" zeros into imaginary fields //Gather real and imaginary parts from workset Eigendata info structure const Epetra_MultiVector& e_r = *(workset.eigenDataPtr->eigenvectorRe); int numVecsInWorkset = e_r.NumVectors(); int numVecsToGather = std::min(numVecsInWorkset, (int)nEigenvectors); for (std::size_t cell=0; cell < workset.numCells; ++cell ) { const Teuchos::ArrayRCP<Teuchos::ArrayRCP<int> >& nodeID = workset.wsElNodeEqID[cell]; for(std::size_t node =0; node < this->numNodes; ++node) { int offsetIntoVec = nodeID[node][0]; // neq==1 hardwired for (std::size_t k = 0; k < numVecsToGather; ++k) { (this->eigenvector_Re[k])(cell,node) = (*(e_r(k)))[offsetIntoVec]; (this->eigenvector_Im[k])(cell,node) = 0.0; } } } } } // else (if both Re and Im are null) gather zeros into both?? }
int do_memory_uplo(int n, W& workspace ) { typedef typename bindings::remove_imaginary<T>::type real_type ; typedef ublas::matrix<T, ublas::column_major> matrix_type ; typedef ublas::vector<real_type> vector_type ; typedef ublas::hermitian_adaptor<matrix_type, UPLO> hermitian_type; // Set matrix matrix_type a( n, n ); a.clear(); vector_type e1( n ); vector_type e2( n ); fill( a ); matrix_type a2( a ); matrix_type z( a ); // Compute Schur decomposition. fortran_int_t m; ublas::vector<fortran_int_t> ifail(n); hermitian_type h_a( a ); lapack::heevx( 'V', 'A', h_a, real_type(0.0), real_type(1.0), 2, n-1, real_type(1e-28), m, e1, z, ifail, workspace ) ; if (check_residual( a2, e1, z )) return 255 ; hermitian_type h_a2( a2 ); lapack::heevx( 'N', 'A', h_a2, real_type(0.0), real_type(1.0), 2, n-1, real_type(1e-28), m, e2, z, ifail, workspace ) ; if (norm_2( e1 - e2 ) > n * norm_2( e1 ) * std::numeric_limits< real_type >::epsilon()) return 255 ; // Test for a matrix range fill( a ); a2.assign( a ); typedef ublas::matrix_range< matrix_type > matrix_range ; typedef ublas::hermitian_adaptor<matrix_range, UPLO> hermitian_range_type; ublas::range r(1,n-1) ; matrix_range a_r( a, r, r ); matrix_range z_r( z, r, r ); ublas::vector_range< vector_type> e_r( e1, r ); ublas::vector<fortran_int_t> ifail_r(n-2); hermitian_range_type h_a_r( a_r ); lapack::heevx( 'V', 'A', h_a_r, real_type(0.0), real_type(1.0), 2, n-1, real_type(1e-28), m, e_r, z_r, ifail_r, workspace ); matrix_range a2_r( a2, r, r ); if (check_residual( a2_r, e_r, z_r )) return 255 ; return 0 ; } // do_memory_uplo()
int do_memory_uplo(int n, W& workspace ) { typedef typename bindings::remove_imaginary<T>::type real_type ; typedef ublas::matrix<T, ublas::column_major> matrix_type ; typedef ublas::symmetric_adaptor<matrix_type, UPLO> symmetric_type ; typedef ublas::vector<real_type> vector_type ; // Set matrix matrix_type a( n, n ); a.clear(); vector_type e1( n ); vector_type e2( n ); fill( a ); matrix_type a2( a ); // Compute eigen decomposition. symmetric_type s_a( a ); lapack::syev( 'V', bindings::noop(s_a), e1, workspace ) ; if (check_residual( a2, e1, a )) return 255 ; symmetric_type s_a2( a2 ); lapack::syev( 'N', s_a2, e2, workspace ) ; if (norm_2( e1 - e2 ) > n * norm_2( e1 ) * std::numeric_limits< real_type >::epsilon()) return 255 ; // Test for a matrix range fill( a ); a2.assign( a ); typedef ublas::matrix_range< matrix_type > matrix_range ; typedef ublas::symmetric_adaptor<matrix_range, UPLO> symmetric_range_type; ublas::range r(1,n-1) ; matrix_range a_r( a, r, r ); ublas::vector_range< vector_type> e_r( e1, r ); symmetric_range_type s_a_r( a_r ); lapack::syev('V', s_a_r, e_r, workspace ); matrix_range a2_r( a2, r, r ); if (check_residual( a2_r, e_r, a_r )) return 255 ; // Test for symmetric_adaptor fill( a ); a2.assign( a ); ublas::symmetric_adaptor< matrix_type, UPLO> a_uplo( a ) ; lapack::syev( 'V', a_uplo, e1, workspace ) ; if (check_residual( a2, e1, a )) return 255 ; return 0 ; } // do_memory_uplo()
NOX::Abstract::Group::ReturnType SaveEigenData_Epetra::save( Teuchos::RCP< std::vector<double> >& evals_r, Teuchos::RCP< std::vector<double> >& evals_i, Teuchos::RCP< NOX::Abstract::MultiVector >& evecs_r, Teuchos::RCP< NOX::Abstract::MultiVector >& evecs_i) { if (nsave==0) return NOX::Abstract::Group::Ok; Teuchos::RCP<NOX::Epetra::MultiVector> ne_r = Teuchos::rcp_dynamic_cast<NOX::Epetra::MultiVector>(evecs_r); Teuchos::RCP<NOX::Epetra::MultiVector> ne_i = Teuchos::rcp_dynamic_cast<NOX::Epetra::MultiVector>(evecs_i); Epetra_MultiVector& e_r = ne_r->getEpetraMultiVector(); Epetra_MultiVector& e_i = ne_i->getEpetraMultiVector(); int ns = nsave; if (ns > evecs_r->numVectors()) ns = evecs_r->numVectors(); for (int i=0; i<ns; i++) { if ((*evals_i)[i]==0) { cout << setprecision(8) << "Eigenvalue " << i << " with value: " << (*evals_r)[i] << "\n Has Eigenvector: " << *(e_r(i)) << "\n" << endl; } else { cout << setprecision(8) << "Eigenvalue " << i << " with value: " << (*evals_r)[i] << " + " << (*evals_i)[i] << " i \nHas Eigenvector Re, Im" << *(e_r(i)) << "\n" << *(e_i(i)) << endl; } } return NOX::Abstract::Group::Ok; }