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()
Exemplo n.º 4
0
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;
}