MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/linalg/superlud.h
Go to the documentation of this file.
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_SUPERLUD_H
00021 #define MECHSYS_SUPERLUD_H
00022 
00023 // SuperLU_DIST
00024 #include <superlu_ddefs.h>
00025 
00026 // MechSys
00027 #include <mechsys/linalg/matvec.h>
00028 #include <mechsys/linalg/sparse_crmatrix.h>
00029 #include <mechsys/util/fatal.h>
00030 #include <mechsys/util/util.h>
00031 
00032 #ifdef DO_DEBUG
00033   #include <iostream>
00034   #include <sstream>
00035   using std::cout;
00036   using std::endl;
00037 #endif
00038 
00039 namespace SuperLUd
00040 {
00041 
00056 inline void Solve(int MyMinEq, int MyMaxEq, int MyNumEqs, int nProcs, int nDOFs, Sparse::CRMatrix<double,int> & AugLocalA, Vec_t & GlobalB)
00057 {
00058 
00059     // Sizes
00060     int m_loc = MyNumEqs; // local number of rows (equations)
00061     int m     = nDOFs;    // global number of rows
00062     int n     = nDOFs;    // global number of cols (must be equal to m for SuperLU_DIST)
00063 
00064     // 1) Set SuperLU distributed matrix ------------------------------------------------
00065     
00066     // Local Aq array
00067     int * Aq = new int [m_loc+1];
00068     for (int i=0; i<m_loc+1; ++i) Aq[i] = AugLocalA.Aq(MyMinEq+i)-AugLocalA.Aq(MyMinEq);
00069     int nz_loc = Aq[m_loc]; // number of non-zeros in the local matrix
00070 
00071     // Create matrix A in the format expected by SuperLU_DIST
00072     int         start = AugLocalA.Aq(MyMinEq);
00073     double const * Ay = &AugLocalA.GetAyPtr()[start];
00074     int    const * Aj = &AugLocalA.GetAjPtr()[start];
00075     NRformat_loc nrfl = { nz_loc, m_loc, MyMinEq, const_cast<double*>(Ay), Aq, const_cast<int*>(Aj) }; // Note: The initialization order of Aq and Aj is different of the order of Ai and Ap for the NCformat!
00076     SuperMatrix  a    = { /*Stype=CRMatrix_dist*/SLU_NR_loc, /*Dtype=double*/SLU_D, /*Mtype=general*/SLU_GE, m, n, &nrfl };
00077 
00078     // 2) Initialize the SuperLU process grid -------------------------------------------
00079     
00080     gridinfo_t           grid;  // grid info
00081     int                  nprow; // number of processors in each row of grid
00082     int                  npcol; // number of processors in each column of grid
00083     Util::FindBestSquare (nProcs, nprow,npcol);
00084     superlu_gridinit     (MPI::COMM_WORLD, nprow, npcol, &grid);
00085 
00086     // Bail out if I do not belong in the grid
00087     if (grid.iam>=nprow*npcol) throw new Fatal(_("SuperLUd::Gesv: SuperLU's grid was not created properly: grid.iam=%d > nprow*npcol=%d"),grid.iam,nprow*npcol);
00088 
00089     // 3) Solve the linear system -------------------------------------------------------
00090 
00091     // Set the input options
00092     superlu_options_t opts;
00093     opts.Fact              = DOFACT;
00094     opts.Equil             = YES;
00095     opts.ColPerm           = MMD_AT_PLUS_A; // NATURAL
00096     opts.Trans             = NOTRANS;
00097     opts.IterRefine        = NOREFINE; // DOUBLE
00098     opts.PrintStat         = NO;
00099     opts.RowPerm           = NOROWPERM; // LargeDiag
00100     opts.ReplaceTinyPivot  = YES;
00101     opts.SolveInitialized  = NO;
00102     opts.RefineInitialized = NO;
00103 
00104     // Initialize ScalePermstruct and LUstruct
00105     ScalePermstruct_t   scp;
00106     LUstruct_t          lus;
00107     ScalePermstructInit (m, n, &scp);
00108     LUstructInit        (m, n, &lus);
00109 
00110     // Initialize the statistics variables
00111     SuperLUStat_t stat;
00112     PStatInit     (&stat);
00113 
00114     // Call the linear equation solver
00115     int           info;
00116     double        berr; // size == nrhs
00117     SOLVEstruct_t svs;
00118     pdgssvx       (&opts, &a, &scp, &GlobalB.data[MyMinEq], /*ldb*/m, /*nrhs*/1, &grid, &lus, &svs, &berr, &stat, &info);
00119 
00120 #ifdef DO_DEBUGx
00121     int rank = MPI::COMM_WORLD.Get_rank();
00122     //LinAlg::Matrix<double> D; AugLocalA.GetDense(D);
00123     std::ostringstream oss;
00124     //oss << "Processor #" << rank << " LocalA=\n" << D << endl;
00125     //oss << "Processor #" << rank << " LocalA=\n" << AugLocalA << endl;
00126     oss<<"Processor #" << rank << " ";
00127     oss<<"Aq={"; for (int i=0; i<m_loc+1; ++i) { oss<<Aq[i];                 if (i!=m_loc)    oss<<","; }; oss<<"} ";
00128     oss<<"Aj={"; for (int i=0; i<nz_loc;  ++i) { oss<<AugLocalA.Aj(start+i); if (i!=nz_loc-1) oss<<","; }; oss<<"} ";
00129     oss<<"Ay={"; for (int i=0; i<nz_loc;  ++i) { oss<<AugLocalA.Ay(start+i); if (i!=nz_loc-1) oss<<","; }; oss<<"} ";
00130     oss<<"B={";  for (int i=0; i<m_loc;   ++i) { oss<<GlobalB(MyMinEq+i);    if (i!=m_loc-1)  oss<<","; }; oss<<"}\n";
00131     cout<<oss.str();
00132     //dPrint_CompRowLoc_Matrix_dist(&a);
00133 #endif
00134 
00135     // Print the statistics
00136     //PStatPrint (&opts, &stat, &grid);
00137 
00138     // 4) Deallocate storage ------------------------------------------------------------
00139 
00140     PStatFree                                 (&stat);
00141     ScalePermstructFree                       (&scp);
00142     Destroy_LU                                (n, &grid, &lus);
00143     LUstructFree                              (&lus);
00144     if (opts.SolveInitialized) dSolveFinalize (&opts, &svs);
00145     delete [] Aq;
00146 
00147     // 5) Release the SuperLU process grid ----------------------------------------------
00148     
00149     superlu_gridexit (&grid);
00150 
00151 }
00152 
00153 }; // namespace SuperLU
00154 
00155 #endif // MECHSYS_SUPERLUD_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines