Back to index

salome-med  6.5.0
MEDSPLITTER_METISGraph.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #ifdef MED_ENABLE_PARMETIS
00021 #include <parmetis.h>
00022 #endif
00023 #ifdef MED_ENABLE_METIS
00024 extern "C" {
00025 #include <metis.h>
00026 }
00027 #endif
00028 
00029 #include "MEDSPLITTER_METISGraph.hxx"
00030 #include "MEDSPLITTER_ParaDomainSelector.hxx"
00031 
00032 using namespace MEDSPLITTER;
00033 
00034 METISGraph::METISGraph():Graph()
00035 {
00036 }
00037 
00038 METISGraph::METISGraph(MEDMEM::MEDSKYLINEARRAY* graph, int* edgeweight)
00039   :Graph(graph,edgeweight)
00040 {
00041 }
00042 
00043 METISGraph::~METISGraph()
00044 {
00045 }
00046 
00047 void METISGraph::partGraph(int                 ndomain,
00048                            const string&       options_string,
00049                            ParaDomainSelector* parallelizer)
00050 {
00051   // number of graph vertices
00052   int n = m_graph->getNumberOf();
00053 
00054   //graph
00055   int * xadj=const_cast<int*>(m_graph->getIndex());
00056   int * adjncy = const_cast<int*>(m_graph->getValue());
00057   //constraints
00058   int * vwgt=m_cellweight;
00059   int * adjwgt=m_edgeweight;
00060   int wgtflag=(m_edgeweight!=0)?1:0+(m_cellweight!=0)?2:0;
00061 
00062   //base 0 or 1
00063   int base=1;
00064 
00065   //ndomain
00066   int nparts = ndomain;
00067 
00068   //options
00069   int options[5]={0,0,0,0,0};
00070 
00071   // output parameters
00072   int edgecut;
00073   int* partition = new int[n];
00074 
00075   if (nparts >1)
00076   {
00077     if ( parallelizer )
00078     {
00079 #ifdef MED_ENABLE_PARMETIS
00080       // distribution of vertices of the graph among the processors
00081       int * vtxdist = parallelizer ? parallelizer->getNbVertOfProcs() : 0;
00082       MPI_Comm comm = MPI_COMM_WORLD;
00083 
00084       ParMETIS_PartKway( vtxdist, xadj, adjncy, vwgt, adjwgt, &wgtflag,
00085                          &base, &nparts, options, &edgecut, partition, &comm );
00086 #else
00087       throw MED_EXCEPTION("ParMETIS is not available. Check your products, please.");
00088 #endif
00089     }
00090     else
00091     {
00092 #ifdef MED_ENABLE_METIS
00093       if (options_string != "k")
00094         METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
00095                                  &base, &nparts, options, &edgecut, partition);
00096       else
00097         METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
00098                             &base, &nparts, options, &edgecut, partition);
00099 #else
00100       throw MED_EXCEPTION("METIS is not available. Check your products, please.");
00101 #endif
00102     }
00103   }
00104   else
00105   {
00106     for (int i=0; i<n; i++)
00107       partition[i]=1;
00108   }
00109 
00110   int* index=new int [n+1];
00111   index[0]=1;
00112   for (int i=0; i<n; i++)
00113   {
00114     index[i+1]=index[i]+1;
00115     partition[i]--;
00116   }
00117 
00118   //creating a skylinearray with no copy of the index and partition array
00119   // the fifth argument true specifies that only the pointers are passed 
00120   //to the object
00121   m_partition = new MEDMEM::MEDSKYLINEARRAY(n,n, index, partition, true);
00122 }
00123