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