コード例 #1
0
///////////////////////////////////////////////////////////////////////////////
/// Entrance of calculating diffusion equation
///
///\param para Pointer to FFD parameters
///\param var Pointer to FFD simulation variables
///\param var_type Type of variable
///\param index Index of trace substance or species
///\param psi Pointer to the variable at current time step
///\param psi0 Pointer to the variable at previous time step
///\param BINDEX Pointer to boundary index
///
///\return 0 if no error occurred
///////////////////////////////////////////////////////////////////////////////
int diffusion(PARA_DATA *para, REAL **var, int var_type, int index,
               REAL *psi, REAL *psi0, int **BINDEX) {
  int flag = 0;

  /****************************************************************************
  | Define the coeffcients for diffusion euqation
  ****************************************************************************/
  flag = coef_diff(para, var, psi, psi0, var_type, index, BINDEX);
  if(flag!=0) {
    ffd_log("diffsuion(): Could not calculate coefficents for "
            "diffusion equation.", FFD_ERROR);
    return flag;
  }

  // Solve the equations
  equ_solver(para, var, var_type, psi);

  // Define B.C.
  set_bnd(para, var, var_type, index, psi, BINDEX);

  // Check residual
  if(para->solv->check_residual==1) {
    switch(var_type) {
      case VX:
        sprintf(msg, "diffusion(): Residual of VX is %f",
                check_residual(para, var, psi));
        ffd_log(msg, FFD_NORMAL);
        break;
      case VY:
        sprintf(msg, "diffusion(): Residual of VY is %f",
                check_residual(para, var, psi));
        ffd_log(msg, FFD_NORMAL);
        break;
      case VZ:
        sprintf(msg, "diffusion(): Residual of VZ is %f",
                check_residual(para, var, psi));
        ffd_log(msg, FFD_NORMAL);
        break;
      case TEMP:
        sprintf(msg, "diffusion(): Residual of T is %f",
                check_residual(para, var, psi));
        ffd_log(msg, FFD_NORMAL);
        break;
      case TRACE:
        sprintf(msg, "diffusion(): Residual of Trace %d is %f",
                index, check_residual(para, var, psi));
        ffd_log(msg, FFD_NORMAL);
        break;
      default:
        sprintf(msg, "diffusion(): No sovler for varibale type %d", 
                var_type);
        ffd_log(msg, FFD_ERROR);
        flag = 1;
    }
  }
       
  return flag;
} // End of diffusion( )
コード例 #2
0
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()
コード例 #3
0
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()
コード例 #4
0
ファイル: qrdemo.cpp プロジェクト: caomw/suitesparse-1
int main (int argc, char **argv)
{
    cholmod_common Common, *cc ;
    cholmod_sparse *A ;
    cholmod_dense *X, *B ;
    int mtype ;
    Long m, n ;

    // start CHOLMOD
    cc = &Common ;
    cholmod_l_start (cc) ;

    // A = mread (stdin) ; read in the sparse matrix A
    A = (cholmod_sparse *) cholmod_l_read_matrix (stdin, 1, &mtype, cc) ;
    if (mtype != CHOLMOD_SPARSE)
    {
        printf ("input matrix must be sparse\n") ;
        exit (1) ;
    }

    // [m n] = size (A) ;
    m = A->nrow ;
    n = A->ncol ;

    printf ("Matrix %6ld-by-%-6ld nnz: %6ld\n", m, n, cholmod_l_nnz (A, cc)) ;

    // B = ones (m,1), a dense right-hand-side of the same type as A
    B = cholmod_l_ones (m, 1, A->xtype, cc) ;

    // X = A\B ; with default ordering and default column 2-norm tolerance
    if (A->xtype == CHOLMOD_REAL)
    {
        // A, X, and B are all real
        X = SuiteSparseQR <double>
            (SPQR_ORDERING_DEFAULT, SPQR_DEFAULT_TOL, A, B, cc) ;
    }
    else
    {
        // A, X, and B are all complex
        X = SuiteSparseQR < std::complex<double> >
            (SPQR_ORDERING_DEFAULT, SPQR_DEFAULT_TOL, A, B, cc) ;
    }

    check_residual (A, X, B, cc) ;
    cholmod_l_free_dense (&X, cc) ;

    // -------------------------------------------------------------------------
    // factorizing once then solving twice with different right-hand-sides
    // -------------------------------------------------------------------------

    // Just the real case.  Complex case is essentially identical
    if (A->xtype == CHOLMOD_REAL)
    {
        SuiteSparseQR_factorization <double> *QR ;
        cholmod_dense *Y ;
        Long i ;
        double *Bx ;

        // factorize once
        QR = SuiteSparseQR_factorize <double>
            (SPQR_ORDERING_DEFAULT, SPQR_DEFAULT_TOL, A, cc) ;

        // solve Ax=b, using the same B as before

        // Y = Q'*B
        Y = SuiteSparseQR_qmult (SPQR_QTX, QR, B, cc) ;
        // X = R\(E*Y)
        X = SuiteSparseQR_solve (SPQR_RETX_EQUALS_B, QR, Y, cc) ;
        // check the results
        check_residual (A, X, B, cc) ;
        // free X and Y
        cholmod_l_free_dense (&Y, cc) ;
        cholmod_l_free_dense (&X, cc) ;

        // repeat with a different B
        Bx = (double *) (B->x) ;
        for (i = 0 ; i < m ; i++)
        {
            Bx [i] = i ;
        }

        // Y = Q'*B
        Y = SuiteSparseQR_qmult (SPQR_QTX, QR, B, cc) ;
        // X = R\(E*Y)
        X = SuiteSparseQR_solve (SPQR_RETX_EQUALS_B, QR, Y, cc) ;
        // check the results
        check_residual (A, X, B, cc) ;
        // free X and Y
        cholmod_l_free_dense (&Y, cc) ;
        cholmod_l_free_dense (&X, cc) ;

        // free QR
        SuiteSparseQR_free (&QR, cc) ;
    }

    // -------------------------------------------------------------------------
    // free everything that remains
    // -------------------------------------------------------------------------

    cholmod_l_free_sparse (&A, cc) ;
    cholmod_l_free_dense (&B, cc) ;
    cholmod_l_finish (cc) ;
    return (0) ;
}