![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
00001 /************************************************************************ 00002 * MechSys - Open Library for Mechanical Systems * 00003 * Copyright (C) 2005 Dorival M. Pedroso, Raul Durand * 00004 * Copyright (C) 2009 Sergio Galindo * 00005 * * 00006 * This program is free software: you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation, either version 3 of the License, or * 00009 * any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License * 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> * 00018 ************************************************************************/ 00019 00020 #ifndef MECHSYS_SUPERLU_H 00021 #define MECHSYS_SUPERLU_H 00022 00023 // SuperLU 00024 #include <slu_ddefs.h> 00025 00026 // MechSys 00027 #include <mechsys/linalg/matvec.h> 00028 #include <mechsys/linalg/sparse_matrix.h> 00029 #include <mechsys/util/fatal.h> 00030 #include <mechsys/util/util.h> 00031 00032 #ifdef DO_DEBUG 00033 using std::cout; 00034 using std::endl; 00035 #endif 00036 00045 namespace SuperLU 00046 { 00047 00052 inline void Solve(Sparse::Matrix<double,int> const & A, Vec_t & X) 00053 { 00054 #ifndef DNDEBUG 00055 if (A.Rows()!=A.Cols()) throw new Fatal("SuperLU::Solve: The matrix A (%d x %d) must be squared.",A.Rows(),A.Cols()); 00056 if (size(X)!=A.Cols()) throw new Fatal("SuperLU::Solve: The vector X (%d x 1) must have a size equal to the number of columns of matrix A (%d)",size(X),A.Cols()); 00057 #endif 00058 00059 // Size 00060 int m = A.Rows(); 00061 int n = A.Cols(); 00062 int nz = A.nZ(); 00063 00064 // Create matrix a in the format expected by SuperLU 00065 NCformat ncf = { nz, const_cast<double*>(A.GetAxPtr()), const_cast<int*>(A.GetAiPtr()), const_cast<int*>(A.GetApPtr()) }; 00066 SuperMatrix a = { /*Stype=column-wise/no-supernode*/SLU_NC, /*Dtype=double*/SLU_D, /*Mtype=general*/SLU_GE, m, n, &ncf }; 00067 00068 // Create right-hand side vector b 00069 DNformat dnf = { m, X.data }; 00070 SuperMatrix b = { /*Stype=dense-storage*/SLU_DN, /*Dtype=double*/SLU_D, /*Mtype=general*/SLU_GE, m, 1, &dnf }; 00071 00072 // Workspaces 00073 int * perm_r = new int [m]; // row permutations from partial pivoting 00074 int * perm_c = new int [n]; // column permutation vector 00075 00076 // Set the default input options 00077 superlu_options_t options; 00078 set_default_options(&options); 00079 options.ColPerm = COLAMD; //NATURAL; 00080 00081 // Initialize the statistics variables 00082 SuperLUStat_t stat; 00083 StatInit(&stat); 00084 00085 // Solve 00086 int info; 00087 SuperMatrix l, u; 00088 dgssv(&options, &a, perm_c, perm_r, &l, &u, &b, &stat, &info); 00089 00090 #ifdef DO_DEBUGx 00091 dPrint_CompCol_Matrix ("a", &a); 00092 dPrint_CompCol_Matrix ("u", &u); 00093 dPrint_SuperNode_Matrix ("l", &l); 00094 #endif 00095 00096 // Cleanup 00097 Destroy_SuperNode_Matrix (&l); 00098 Destroy_CompCol_Matrix (&u); 00099 StatFree (&stat); 00100 delete [] perm_r; 00101 delete [] perm_c; 00102 00103 } 00104 00105 }; // namespace SuperLU 00106 00107 #endif // MECHSYS_SUPERLU_H