Beispiel #1
0
  void OneD_Node_Mesh<_Type, _Xtype>::set_nodes_vars( const std::size_t node, const DenseVector<_Type>& U )
  {
#ifdef PARANOID
    if ( U.size() != NV )
    {
      std::string problem;
      problem = " The OneD_Node_Mesh.set_node method is trying to add \n";
      problem += " an NVector of variables of a different size to that \n";
      problem += " stored at other nodal points. \n";
      throw ExceptionGeom( problem, NV, U.size() );
    }
#endif
    for ( std::size_t var = 0; var < U.size(); ++var )
    {
      VARS[ node * NV + var ] = U[ var ];
    }
  }
Beispiel #2
0
  void DenseLinearEigenSystem<double>::eigensolve_lapack_without_vectors()
  {
#ifndef LAPACK
    std::string problem;
    problem = "The DenseLinearEigenSystem::eigensolve_lapack_without_vectors method has been called\n";
    problem += "but the compiler option -DLAPACK was not provided when\n";
    problem += "the library was built.";
    throw ExceptionExternal( problem );
#else

    std::size_t N = p_A -> nrows();
    // Cache issues of varying significance plague problems of size 2^j + 2^k + ...
    // when LDA = N, so this is my shameless 'tweak' to maintain predictable
    // performance, at least for N <=1024 or so.
    int padding( 0 );
    if ( ( N % 2 == 0 ) && ( N > 127 ) )
    {
      padding = 1;
    }
#ifdef PARANOID
    if ( ( p_A -> nrows() != p_B -> nrows() ) ||
         ( p_A -> ncols() != p_B -> ncols() ) )
    {
      std::string problem( "The DenseLinearEigenSystem::eigensolve_lapack_without_vectors method has detected a failure \n" );
      throw ExceptionGeom( problem, p_A -> nrows(), p_A -> ncols(),
                           p_B -> nrows(), p_B -> ncols() );
    }
#endif
    FortranData Af( *p_A, true, padding );
    FortranData Bf( *p_B, true, padding );
    // eigenvalue storage
    DenseVector<double> alpha_r( N, 0.0 );
    DenseVector<double> alpha_i( N, 0.0 );
    DenseVector<double> beta( N, 0.0 );
    // eigenvector storage
    DenseVector<double> vec_left( 1, 0.0 );
    DenseVector<double> vec_right( 1, 0.0 );
    // some workspace for the LAPACK routine
    DenseVector<double> work( 1, 0.0 );
    int info( 0 );
    // Call FORTRAN LAPACK to get the required workspace
    LAPACK_DGGEV( ( char* ) "N", ( char* ) "N", N, Af.base(), N + padding, Bf.base(), N + padding, &alpha_r[ 0 ], &alpha_i[ 0 ], &beta[ 0 ], &vec_left[ 0 ], 1, &vec_right[ 0 ], 1, &work[ 0 ], -1, info );
    int required_workspace = ( int ) work[ 0 ];
#ifdef DEBUG

    std::cout << " [DEBUG] DenseLinearEigenSystem::eigensolve_lapack_without_vectors is requesting \n";
    std::cout << " [DEBUG] a workspace vector of size " << required_workspace << "\n";
#endif

    work.resize( required_workspace );
    // call FORTRAN LAPACK again with the optimum workspace
    LAPACK_DGGEV( ( char* ) "N", ( char* ) "N", N, Af.base(), N + padding, Bf.base(), N + padding, &alpha_r[ 0 ], &alpha_i[ 0 ], &beta[ 0 ], &vec_left[ 0 ], 1, &vec_right[ 0 ], 1, &work[ 0 ], required_workspace, info );
    if ( 0 != info )
    {
      std::string problem( "The DenseLinearEigenSystem::eigensolve_lapack_without_vectors method has detected a failure. \n" );
      throw ExceptionExternal( problem, info );
    }
    // create a complex eigenvalue vector
    EIGENVALUES_ALPHA = DenseVector<D_complex>( N, 0.0 );
    for ( std::size_t i = 0; i < N; ++i )
    {
      const D_complex eye( 0.0, 1.0 );
      EIGENVALUES_ALPHA[ i ] = alpha_r[ i ] + alpha_i[ i ] * eye;
    }
    // set the eigenvalue member data
    EIGENVALUES_BETA = beta;
#endif

  }
Beispiel #3
0
  void DenseLinearEigenSystem< double >::eigensolve_lapack_with_vectors()
  {
#ifndef LAPACK
    std::string problem;
    problem = "The DenseLinearEigenSystem::eigensolve_lapack_with_vectors method has been called\n";
    problem += "but the compiler option -DLAPACK was not provided when\n";
    problem += "the library was built.";
    throw ExceptionExternal( problem );
#else

    std::size_t N = p_A -> nrows();
    // Cache contention issues of varying significance plague problems of size 2^j + 2^k + ...
    // when LDA = N, so this is my shameless 'tweak' to maintain predictable
    // performance, at least for N <=1024 or so.
    int padding( 0 );
    if ( ( N % 2 == 0 ) && ( N > 127 ) )
    {
      padding = 1;
    }
#ifdef PARANOID
    if ( ( p_A -> nrows() != p_B -> nrows() ) ||
         ( p_A -> ncols() != p_B -> ncols() ) )
    {
      std::string problem( "The DenseLinearEigenSystem::eigensolve_lapack_with_vectors method has detected a failure. \n" );
      throw ExceptionGeom( problem, p_A -> nrows(), p_A -> ncols(),
                           p_B -> nrows(), p_B -> ncols() );
    }
#endif
    // Convert to fortran data  incl. a transpose of the
    // input matrices so they are in column_major format then include padding
    FortranData Af( *p_A, true, padding );
    FortranData Bf( *p_B, true, padding );
    // eigenvalue storage
    DenseVector<double> alpha_r( N, 0.0 );
    DenseVector<double> alpha_i( N, 0.0 );
    DenseVector<double> beta( N, 0.0 );
    // new the right eigenvector storage
    DenseVector<double> vec_left( 1, 0.0 );
    DenseVector<double> vec_right( N * N, 0.0 );
    // some workspace for the LAPACK routine
    DenseVector<double> work( 1, 0.0 );
    // return integer for LAPACK
    int info( 0 );
    // Call FORTRAN LAPACK to get the required workspace
    LAPACK_DGGEV( ( char* ) "N", ( char* ) "V", N, Af.base(), N + padding, Bf.base(), N + padding, &alpha_r[ 0 ], &alpha_i[ 0 ], &beta[ 0 ], &vec_left[ 0 ], 1, &vec_right[ 0 ], N, &work[ 0 ], -1, info );
    int required_workspace = 4 * int( work[ 0 ] );
#ifdef DEBUG

    std::cout << "[DEBUG] DenseLinearEigenSystem::eigensolve_lapack_with_vectors is requesting \n";
    std::cout << "[DEBUG] a workspace vector of size " << required_workspace << "\n";
#endif

    work.resize( required_workspace );
    // call FORTRAN LAPACK again with the optimum workspace
    LAPACK_DGGEV( ( char* ) "N", ( char* ) "V", N, Af.base(), N + padding, Bf.base(), N + padding, &alpha_r[ 0 ], &alpha_i[ 0 ], &beta[ 0 ], &vec_left[ 0 ], 1, &vec_right[ 0 ], N, &work[ 0 ], required_workspace, info );
    if ( 0 != info )
    {
      std::string problem( "The DenseLinearEigenSystem::eigensolve_lapack_with_vectors method has detected a failure.\n" );
      throw ExceptionExternal( problem, info );
    }
    // create a complex eigenvalue vector
    EIGENVALUES_ALPHA = DenseVector<D_complex>( N, 0.0 );
    // complex eigenvector matrix
    ALL_EIGENVECTORS = DenseMatrix<D_complex>( N, N, 0.0 );
    // step through the eigenvalues
    for ( std::size_t i = 0; i < N; ++i )
    {
      const D_complex eye( 0.0, 1.0 );
      // make the complex vector of alpha
      EIGENVALUES_ALPHA[ i ] = alpha_r[ i ] + alpha_i[ i ] * eye;
      if ( std::abs( alpha_i[ i ] ) > 0.0 )
      {
        // eigenvector is complex
        for ( std::size_t k = 0; k < N; ++k )
        {
          ALL_EIGENVECTORS[ i ][ k ] = vec_right[ i * N + k ] + eye * vec_right[ ( i + 1 ) * N + k ];
          // store the conjugate too for completeness
          ALL_EIGENVECTORS[ i + 1 ][ k ] = vec_right[ i * N + k ] - eye * vec_right[ ( i + 1 ) * N + k ];
        }
        ++i;
      }
      else // eigenvector is real
      {
        for ( std::size_t k = 0; k < N; ++k )
        {
          ALL_EIGENVECTORS( i, k ) = vec_right[ i * N + k ];
        }
      }
    }
    // set the eigenvalue member data
    EIGENVALUES_BETA = beta;
#endif

  }