MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/linalg/mumps.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_MUMPS_H
00021 #define MECHSYS_MUMPS_H
00022 
00023 // MUMPS
00024 #ifdef HAS_MPI
00025  extern "C" {
00026    #include "dmumps_c.h"
00027  }
00028 #endif
00029 
00030 // MechSys
00031 #include <mechsys/linalg/matvec.h>
00032 #include <mechsys/linalg/sparse_triplet.h>
00033 #include <mechsys/util/fatal.h>
00034 
00035 namespace MUMPS
00036 {
00037 
00046 inline void Solve (Sparse::Triplet<double,int> & A, Vec_t const & B, Vec_t & X, bool Prod=false)
00047 {
00048 #ifdef HAS_MPI
00049     // collect B from all processors into X==RHS in processor # 0
00050     int neq = A.Rows();
00051     if (Prod)
00052     {
00053         MPI::COMM_WORLD.Reduce (B.data, X.data, neq, MPI::DOUBLE, MPI::PROD, /*dest*/0);
00054     }
00055     else
00056     {
00057         MPI::COMM_WORLD.Reduce (B.data, X.data, neq, MPI::DOUBLE, MPI::SUM, /*dest*/0);
00058     }
00059 
00060     // initialize MUMPS
00061     DMUMPS_STRUC_C ms;
00062     ms.comm_fortran = -987654;
00063     ms.sym          =  0;    // 0=unsymmetric, 1=sym(pos-def), 2=symmetric(undef)
00064     ms.par          =  1;    // host also works
00065     ms.job          = -1;    // initialisation code
00066     dmumps_c (&ms);          // do initialize
00067 
00068     // set matrix and rhs
00069     A.IncIndices (1); // increment indices since MUMS is 1-based (FORTRAN)
00070     ms.n       = neq;
00071     ms.nz_loc  = A.Top();
00072     ms.irn_loc = A.GetAiPtr();
00073     ms.jcn_loc = A.GetAjPtr();
00074     ms.a_loc   = A.GetAxPtr();
00075     if (MPI::COMM_WORLD.Get_rank()==0) ms.rhs = X.data; // only proc # 0 needs the RHS
00076 
00077     // solve
00078     ms.icntl[1  -1] = -1;    // no output messages
00079     ms.icntl[2  -1] = -1;    // no warnings
00080     ms.icntl[3  -1] = -1;    // no global information
00081     ms.icntl[4  -1] = -1;    // message level
00082     ms.icntl[5  -1] =  0;    // assembled matrix (needed for distributed matrix)
00083     ms.icntl[7  -1] =  5;    // use metis for pivoting
00084     ms.icntl[8  -1] =  0;    // no scaling
00085     ms.icntl[18 -1] =  3;    // distributed matrix
00086     ms.job          =  6;    // reorder, factor and solve codes
00087     dmumps_c (&ms);          // do solve
00088     int info = ms.info[1-1]; // info code
00089 
00090     // finalize MUMPS
00091     ms.job = -2;    // finalize code
00092     dmumps_c (&ms); // do finalize
00093 
00094     // check for errors
00095     if (info<0)
00096     {
00097         switch (info)
00098         {
00099             case -6:  throw new Fatal("MUMPS::Solve: Error # -6: singular matrix");
00100             case -10: throw new Fatal("MUMPS::Solve: Error # -10: singular matrix");
00101             case -13: throw new Fatal("MUMPS::Solve: Error # -13: out of memory");
00102             default:  throw new Fatal("MUMPS::Solve: Error # %d: unknown error",info);
00103         }
00104     }
00105 
00106     // distribute solution
00107     MPI::COMM_WORLD.Bcast (X.data, neq, MPI::DOUBLE, /*from*/0);
00108 
00109 #else
00110     throw new Fatal("MUMPS::Solve: This method requires the flag HAS_MPI");
00111 #endif
00112 }
00113 
00114 }; // namespace MUMPS
00115 
00116 #endif // MECHSYS_MUMPS_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines