Back to index

salome-med  6.5.0
MEDPARTITIONER_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 #include "MEDPARTITIONER_MetisGraph.hxx"
00021 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
00022 #include "MEDPARTITIONER_Utils.hxx"
00023 
00024 #include "InterpKernelException.hxx"
00025 
00026 #include <iostream>
00027 
00028 #ifdef MED_ENABLE_METIS
00029 extern "C"
00030 {
00031 #include "metis.h"
00032 }
00033 #endif
00034 
00035 using namespace MEDPARTITIONER;
00036 
00037 METISGraph::METISGraph():Graph()
00038 {
00039 }
00040 
00041 METISGraph::METISGraph(MEDPARTITIONER::SkyLineArray* graph, int* edgeweight)
00042   :Graph(graph,edgeweight)
00043 {
00044 }
00045 
00046 METISGraph::~METISGraph()
00047 {
00048 }
00049 
00050 void METISGraph::partGraph(int ndomain,
00051                            const std::string& options_string,
00052                            ParaDomainSelector *parallelizer)
00053 {
00054   using std::vector;
00055   if (MyGlobals::_Verbose>10)
00056     std::cout << "proc " << MyGlobals::_Rank << " : METISGraph::partGraph" << std::endl;
00057   
00058   //number of graph vertices
00059   int n=_graph->getNumberOf();
00060   //graph
00061   int * xadj=const_cast<int*>(_graph->getIndex());
00062   int * adjncy=const_cast<int*>(_graph->getValue());
00063   //constraints
00064   int * vwgt=_cell_weight;
00065   int * adjwgt=_edge_weight;
00066   int wgtflag=(_edge_weight!=0)?1:0+(_cell_weight!=0)?2:0;
00067   //base 0 or 1
00068   int base=0;
00069   //ndomain
00070   int nparts=ndomain;
00071   //options
00072   /*
00073     (0=default_option,option,random_seed) see defs.h
00074     #define PMV3_OPTION_DBGLVL 1
00075     #define PMV3_OPTION_SEED 2
00076     #define PMV3_OPTION_IPART 3
00077     #define PMV3_OPTION_PSR 3
00078     seems no changes int options[4]={1,0,33,0}; //test for a random seed of 33
00079   */
00080   int options[4]={0,0,0,0};
00081 #if !defined(MED_ENABLE_METIS)
00082   throw INTERP_KERNEL::Exception("METISGraph::partGraph : METIS is not available. Check your products, please.");
00083 #else
00084   //output parameters
00085   int edgecut;
00086   int* partition=new int[n];
00087 
00088   if(nparts >1)
00089     {
00090       if (MyGlobals::_Verbose>10) 
00091         std::cout << "METISGraph::partGraph METIS_PartGraph METIS_PartGraph(RecursiveOrKway)" << std::endl;
00092       if (options_string != "k")
00093         METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
00094                                   &base, &nparts, options, &edgecut, partition);
00095       else
00096         METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag,
00097                             &base, &nparts, options, &edgecut, partition);
00098     }
00099   else  //force this case because METIS send all 1 in value
00100     {
00101       for (int i=0; i<n; i++)
00102         partition[i]=0;
00103     }
00104   vector<int> index(n+1);
00105   vector<int> value(n);
00106   index[0]=0;
00107   for (int i=0; i<n; i++)
00108     {
00109       index[i+1]=index[i]+1;
00110       value[i]=partition[i];
00111     }
00112   delete [] partition;
00113 
00114   //creating a skylinearray with no copy of the index and partition array
00115   //the fifth argument true specifies that only the pointers are passed 
00116   //to the object
00117   _partition = new MEDPARTITIONER::SkyLineArray(index,value);
00118 #endif
00119 }
00120