00001
00004
00005
00006
00007 #include "cscmatrix.h"
00008 #include "std_cplx.h"
00009
00010 #ifdef HAVE_SUPERLU3_INCLUDES
00011 # include <superlu/slu_zdefs.h>
00012 # include <superlu/supermatrix.h>
00013 # include <superlu/slu_util.h>
00014 #else
00015 # include "superlu/util.h"
00016 # include "superlu/zsp_defs.h"
00017 #endif
00018
00019 #if TBCI_NUMLIB_VERSION >= 20600
00020 # define COLPERM_T_DECLARED
00021 # include "solver/superlu_stdcplx.h"
00022 #endif
00023
00024 #ifdef HAVE_UNISTD_H
00025 #include "unistd.h"
00026 #endif
00027
00028 NAMESPACE_TBCI
00029
00030 int lu_solve(CSCMatrix< CPLX__ complex<double> >& M,
00031 Vector< CPLX__ complex<double> >& x,
00032 const Vector< CPLX__ complex<double> >& rhs,
00033 colperm_t permc_spec,
00034 bool verbose, bool symm)
00035 {
00036 int nrhs = 1;
00037 int m = M.rows();
00038 int n = M.columns();
00039 int nnz = M.size();
00040 doublecomplex *a= (doublecomplex*) M.dataPointer();
00041 unsigned int *asub= M.rowIndexPointer();
00042 unsigned int *xa = M.columnPointer();
00043
00044 int *perm_r;
00045 int *perm_c;
00046 SuperMatrix A;
00047 SuperMatrix B;
00048 SuperMatrix L;
00049 SuperMatrix U;
00050
00051 int info;
00052 #ifdef HAVE_SUPERLU3_INCLUDES
00053 superlu_options_t slu_opt;
00054 SuperLUStat_t slu_stat;
00055 set_default_options(&slu_opt);
00056 slu_opt.ColPerm = permc_spec;
00057 slu_opt.SymmetricMode = (yes_no_t)symm;
00058 if (symm)
00059 slu_opt.DiagPivotThresh = 0.1;
00060 slu_opt.PrintStat = (yes_no_t)verbose;
00061 StatInit(&slu_stat);
00062 #elif defined(HAVE_UNISTD_H)
00063 int savedstdout = 0;
00064 #endif
00065
00066
00067 x = rhs;
00068
00069 zCreate_CompCol_Matrix(&A, m, n, nnz, a, (int*)asub, (int*)xa, SLU_NC, SLU_Z, SLU_GE);
00070 zCreate_Dense_Matrix(&B, m, nrhs, (doublecomplex*) x.get_fortran_vector(),
00071 m, SLU_DN, SLU_Z, SLU_GE);
00072 if ( !(perm_r = intMalloc(m)) )
00073 ABORT("Malloc fails for perm_r[].");
00074 if ( !(perm_c = intMalloc(n)) )
00075 ABORT("Malloc fails for perm_c[].");
00076
00077 #if defined(HAVE_UNISTD_H) && !defined(HAVE_SUPERLU3_INCLUDES)
00078
00079 if (!verbose) {
00080 savedstdout = dup(STDOUT_FILENO); close(STDOUT_FILENO);
00081 }
00082 #endif
00083 #ifndef HAVE_SUPERLU3_INCLUDES
00084
00085 get_perm_c(permc_spec, &A, perm_c);
00086 #endif
00087
00088
00089 #ifdef HAVE_SUPERLU3_INCLUDES
00090 zgssv(&slu_opt, &A, perm_c, perm_r, &L, &U, &B, &slu_stat, &info);
00091 if (verbose)
00092 StatPrint(&slu_stat);
00093 #else
00094 zgssv(&A, perm_c, perm_r, &L, &U, &B, &info);
00095 #endif
00096 #if defined(HAVE_UNISTD_H) && !defined(HAVE_SUPERLU3_INCLUDES)
00097
00098 if (!verbose) {
00099 dup(savedstdout); close(savedstdout);
00100 }
00101 #endif
00102
00103 if (info != 0) {
00104 fprintf(stderr, "SuperLU: zgssv() error returns INFO= %d\n", info);
00105 if (info > n) {
00106
00107 mem_usage_t mem_usage;
00108 #ifdef HAVE_SUPERLU3_INCLUDES
00109 zQuerySpace(&L, &U, &mem_usage);
00110 #else
00111 int panel_size = sp_ienv(1);
00112 zQuerySpace(&L, &U, panel_size, &mem_usage);
00113 #endif
00114 fprintf(stderr, "SuperLU: Memory allocation of %i bytes failed!\n",
00115 info - n);
00116 fprintf(stderr, " L\\U MB %.3f\ttotal MB needed %.3f\texpansions %d\n",
00117 mem_usage.for_lu/1e6, mem_usage.total_needed/1e6,
00118 mem_usage.expansions);
00119 } else
00120 fprintf(stderr, "SuperLU: Singular factor U(%i,%i) found!\n", info, info);
00121 }
00122
00123 SUPERLU_FREE(perm_r);
00124 SUPERLU_FREE(perm_c);
00125 Destroy_SuperNode_Matrix(&L);
00126 Destroy_CompCol_Matrix(&U);
00127
00128 Destroy_SuperMatrix_Store(&B);
00129 Destroy_SuperMatrix_Store(&A);
00130 #ifdef HAVE_SUPERLU3_INCLUDES
00131 StatFree(&slu_stat);
00132 #endif
00133
00134 return info;
00135 }
00136
00137 #if TBCI_NUMLIB_VERSION < 20600
00138
00141 WEAK(
00142 TVector< CPLX__ complex<double> > lu_solve(CSCMatrix< CPLX__ complex<double> >& M,
00143 const Vector< CPLX__ complex<double> >& rhs,
00144 colperm_t permc_spec,
00145 bool verbose, bool symm)
00146 )
00147 {
00148 TVector< CPLX__ complex<double> > x(rhs.size());
00149 const int info = lu_solve(M, (Vector< CPLX__ complex<double> >&)x,
00150 rhs, permc_spec, verbose, symm);
00151 return x;
00152 }
00153 #endif
00154
00155 NAMESPACE_END