<p><b>dwj07@fsu.edu</b> 2011-12-14 22:14:11 -0700 (Wed, 14 Dec 2011)</p><p><br>
        -- BRANCH COMMIT --<br>
<br>
        Adding a tool that can be used to create weighted graph decompositions of mpas grids.<br>
<br>
        Included is a README file which describes how to use it.<br>
<br>
        Current weighted is on maxLevelCell only, but can be extended to use any field in an mpas grid.<br>
<br>
        One call can generate many graph.info.part.N files.<br>
</p><hr noshade><pre><font color="gray">Added: branches/tools/weighted_graphs/Makefile
===================================================================
--- branches/tools/weighted_graphs/Makefile         (rev 0)
+++ branches/tools/weighted_graphs/Makefile        2011-12-15 05:14:11 UTC (rev 1257)
@@ -0,0 +1,14 @@
+CXX=g++
+CFLAGS= -O3 -m64
+DFLAGS= -g -m64
+METISLIBDIR=/home/douglasj/softwares/metis-5.0.2/build/Linux-x86_64/libmetis
+METISINCDIR=/home/douglasj/softwares/metis-5.0.2/include
+EXECUTABLE=makeGraphs.x
+
+
+all:
+        ${CXX} ${CFLAGS} -I${METISINCDIR} -I${NETCDF}/include weightedGraphs.cpp -o ${EXECUTABLE} -L${METISLIBDIR} -L${NETCDF}/lib -lstdc++ -lnetcdf_c++ -lmetis
+debug:
+        ${CXX} ${DFLAGS} -I${METISINCDIR} -I${NETCDF}/include weightedGraphs.cpp -o ${EXECUTABLE} -L${METISLIBDIR} -L${NETCDF}/lib -lstdc++ -lnetcdf_c++ -lmetis
+clean:
+        rm -f ${EXECUTABLE} graph.*
Added: branches/tools/weighted_graphs/README
===================================================================
--- branches/tools/weighted_graphs/README         (rev 0)
+++ branches/tools/weighted_graphs/README        2011-12-15 05:14:11 UTC (rev 1257)
@@ -0,0 +1,38 @@
+Weighted Graph Partitioner
+Author: Doug Jacobsen
+Date: 12/14/2011
+
+weightedGraphs.cpp:
+        This program is meant to call metis to make create weighted graph.info.part.N files
+        for an MPAS grid. Given that the grid contains cellsOnCell, and maxLevelCell. If
+        maxLevelCell is not present, the weights default to 1.
+
+        Currently the field maxLevelCell is hardcoded in the program, but can be extended
+        to use any field. The field has to be converted to an integer weight though.
+
+Building:
+        To build, you need to have metis 5.0.2 or newer. Older may work, but that has not been tested.
+        The makefile needs to be updated with the paths to metis.h and libmetis.a (after it's built).
+        Then makeGraphs.x can be build by typing
+                make
+
+Usage:
+        To run, after building the usage is as follows:
+                ./makeGraphs.x [gridfile] [proc_list]
+
+        gridfile:
+                default - grid.nc
+                Can be any grid name, and is required if proc_list is to be provided.
+
+        proc_list:
+                default - 2 4 8 16 32
+                Entered as a list of integers, for which to make the graph.info.part.N file for.
+                Each one will create a separate graph.info.part file.
+
+        Example:
+                ./makeGraphs.x x1.2562.grid.nc 64 128 256
+                Will create graph.info.part.64, graph.info.part.128, and graph.info.part.256 files.
+                Each will be made for use with the x1.2562.grid.nc file that was used as input.
+
+This program can also be used as an example of how to call metis from a c++ code, for the serial generation
+a graph decomposition.
Added: branches/tools/weighted_graphs/weightedGraphs.cpp
===================================================================
--- branches/tools/weighted_graphs/weightedGraphs.cpp         (rev 0)
+++ branches/tools/weighted_graphs/weightedGraphs.cpp        2011-12-15 05:14:11 UTC (rev 1257)
@@ -0,0 +1,271 @@
+#include <iostream>
+#include <fstream>
+#include <cstdlib>
+#include <vector>
+#include <string>
+#include <sstream>
+
+#include <netcdfcpp.h>
+#include <metis.h>
+
+using namespace std;
+
+void init_metis();
+
+int netcdf_mpas_read_dim ( string filename, string dim_name );
+void netcdf_mpas_read_cellsoncell ( string filename, int *cellsoncell );
+void netcdf_mpas_read_maxlevelcell ( string filename, int *maxlevelcell );
+void make_graphs(int *cellsOnCell, int *weights);
+
+vector<idx_t> proc_list;
+vector<idx_t>::iterator proc_itr;
+int nCells, nVertices, nEdges, maxEdges;
+idx_t options[METIS_NOPTIONS];
+
+
+int main(int argc, char** argv){
+        int i, j;
+        int *cellsOnCell, *maxLevelCell;
+        string gridfile;
+        ofstream graph("graph.info");
+
+        if(argc >= 2){
+                gridfile = argv[1];
+        } else {
+                gridfile = "grid.nc";
+        }
+
+        if (argc > 2) {
+                for(i = 2; i < argc; i++){
+                        proc_list.push_back(atoi(argv[i]));        
+                }
+        } else {
+                proc_list.push_back(2);
+                proc_list.push_back(4);
+                proc_list.push_back(8);
+                proc_list.push_back(16);
+                proc_list.push_back(32);
+        }
+
+        cout << "Filename: " << gridfile << endl;
+
+        NcFile grid_check ( gridfile.c_str ( ), NcFile::ReadOnly );
+        if(!grid_check.is_valid()){
+                cout << "Grid file " << gridfile << " does not exist. Exiting." << endl;
+                grid_check.close();
+                return 1;
+        }
+        grid_check.close();
+
+        cout << "Reading nCells" << endl;
+        nCells = netcdf_mpas_read_dim(gridfile, "nCells");
+        cout << "Reading nVertices" << endl;
+        nVertices = netcdf_mpas_read_dim(gridfile, "nVertices");
+        cout << "Reading nEdges" << endl;
+        nEdges = netcdf_mpas_read_dim(gridfile, "nEdges");
+        cout << "Reading maxEdges" << endl;
+        maxEdges = netcdf_mpas_read_dim(gridfile, "maxEdges");
+
+        cellsOnCell = new int[nCells * maxEdges];
+        maxLevelCell = new int[nCells];
+
+        cout << "Reading cellsOnCell" << endl;
+        netcdf_mpas_read_cellsoncell(gridfile, cellsOnCell);
+        cout << "Reading maxLevelCell" << endl;
+        netcdf_mpas_read_maxlevelcell(gridfile, maxLevelCell);
+
+        graph << nCells << " " << nEdges << " 010" << endl;
+
+        for(i = 0; i < nCells; i++){
+                graph << maxLevelCell[i] << " ";
+                for(j = 0; j < maxEdges; j++){
+                        if(cellsOnCell[i * maxEdges + j] > 0){
+                                graph << cellsOnCell[i * maxEdges + j] << " ";
+                        }
+                }
+                graph << endl;
+        }
+
+        graph.close();
+
+        init_metis();
+        make_graphs(cellsOnCell, maxLevelCell);
+
+        return 0;
+}
+
+void init_metis(){/*{{{*/
+        METIS_SetDefaultOptions(options);
+        options[METIS_OPTION_PTYPE] = METIS_PTYPE_RB;
+//        options[METIS_OPTION_OBJTYPE] = METIS_OBJTYPE_VOL;
+//        options[METIS_OPTION_CTYPE] = METIS_CTYPE_RM;
+        options[METIS_OPTION_IPTYPE] = METIS_IPTYPE_RANDOM;
+        options[METIS_OPTION_NCUTS] = 10;
+        options[METIS_OPTION_NUMBERING] = 0;
+//        options[METIS_OPTIONS_NITER] = 50;
+}/*}}}*/
+
+int netcdf_mpas_read_dim ( string filename, string dim_name ){/*{{{*/
+        //****************************************************************************80
+        //
+        // Purpose:
+        //
+        // NETCDF_MPAS_READ_DIM gets the size of the dimension with name dim_name
+        //
+        // Licensing:
+        //
+        // This code is distributed under the GNU LGPL license.
+        //
+        // Modified:
+        //
+        // 29 December 2010
+        //
+        // Author:
+        //
+        // John Burkardt, Doug Jacobsen
+        //
+        // Reference:
+        //
+        // Russ Rew, Glenn Davis, Steve Emmerson, Harvey Davies, Ed Hartne,
+        // The NETCDF User's Guide,
+        // Unidata Program Center, March 2009.
+        //
+        // Parameters:
+        //
+        // Input, string NC_FILENAME, the name of the NETCDF file to examine.
+        //
+        // Input, string DIM_NAME, the name of the dimension in question
+        //
+        // Output, int NETCDF_MPAS_READ_DIM, the value of the dimension.
+        //
+        int ntime;
+        long int dim_size;
+        NcDim *dim_id;
+        bool valid;
+        string tmp_name;
+        //
+        // Open the file.
+        NcFile ncid ( filename.c_str ( ), NcFile::ReadOnly );
+        //
+        //
+        // Get Ntime, which is a NETCDF dimension.
+        //
+        valid = false;
+
+        for(int i = 0; i < ncid.num_dims() && !valid; i++){
+                tmp_name = ncid.get_dim(i)->name();
+
+                if(dim_name == tmp_name){
+                        valid = true;
+                }
+        }
+
+        if(valid){
+                dim_id = ncid.get_dim(dim_name.c_str());
+                dim_size = (*dim_id).size ( );
+        } else {
+                dim_size = 1;
+        }
+        //
+        // Close the file.
+        //
+        ncid.close ( );
+
+        ntime = ( int ) dim_size;
+
+        return ntime;
+}/*}}}*/
+
+void netcdf_mpas_read_cellsoncell ( string filename, int *cellsoncell ){/*{{{*/
+        NcVar *var_id;
+        NcError err = NcError( NcError::verbose_nonfatal );
+        NcFile ncid ( filename.c_str ( ), NcFile::ReadOnly );
+
+        var_id = ncid.get_var ( "cellsOnCell" );
+        (*var_id).get ( &cellsoncell[0], nCells, maxEdges );
+
+        ncid.close ( );
+
+        return;
+}/*}}}*/
+
+void netcdf_mpas_read_maxlevelcell ( string filename, int *maxlevelcell ){/*{{{*/
+        NcVar *var_id;
+        NcError err = NcError( NcError::silent_nonfatal );
+        NcFile ncid ( filename.c_str ( ), NcFile::ReadOnly );
+        //
+        //
+        // Get the variable values.
+        //
+        if (!(var_id = ncid.get_var ( "maxLevelCell" ))){
+                for(int i = 0; i < nCells; i++){
+                        maxlevelcell[i] = 1;
+                }
+        } else {
+                (*var_id).get ( &maxlevelcell[0], nCells );
+        }
+
+        ncid.close ( );
+
+        return;
+}/*}}}*/
+
+void make_graphs(int *cellsOnCell, int *weights){/*{{{*/
+        int edgeCount, edgePos;
+        int i, j;
+        idx_t nvtxs, ncon, nparts, objval;
+        idx_t *xadj, *adjncy, *vwgt, *graph_out;
+
+        nvtxs = nCells;
+        ncon = 1;
+        nparts = 4;
+
+        edgeCount = 0;
+
+        for(i = 0; i < nCells; i++){
+                for(j = 0; j < maxEdges; j++){
+                        if(cellsOnCell[i * maxEdges + j] > 0){
+                                edgeCount++;
+                        }
+                }
+        }
+
+        cout << "Counted " << edgeCount << " edges." << endl;
+
+        graph_out = new idx_t[nCells];
+        vwgt = new idx_t[nCells];
+        xadj = new idx_t[nCells+1];
+        adjncy = new idx_t[edgeCount];
+
+        xadj[nCells] = edgeCount-1;
+
+        edgePos = 0;
+        for(i = 0; i < nCells; i++){
+                xadj[i] = edgePos;
+                edgeCount = 0;
+                for(j = 0; j < maxEdges; j++){
+                        if(cellsOnCell[i * maxEdges + j] > 0){
+                                adjncy[edgePos] = cellsOnCell[i * maxEdges + j] - 1;
+                                edgeCount++;
+                                edgePos++;
+                        }
+                }
+                vwgt[i] = weights[i];
+        }
+
+        for(proc_itr = proc_list.begin(); proc_itr != proc_list.end(); proc_itr++){
+                stringstream outname;
+                nparts = (*proc_itr);
+                cout << "Making graph with " << nparts << " partitions." << endl;
+                METIS_PartGraphRecursive(&nvtxs, &ncon, xadj, adjncy, vwgt, NULL, NULL, &nparts, NULL, NULL, options, &objval, graph_out);
+
+                outname << "graph.info.part." << nparts;
+                ofstream g_out(outname.str().c_str());
+                for(i = 0; i < nCells; i++){
+                        g_out << graph_out[i] << endl;
+                }
+                g_out.close();
+        }
+
+}/*}}}*/
+
</font>
</pre>