Skip to content
Snippets Groups Projects
Select Git revision
  • 509e02db33faf9d6cc2a19112382e765ed5b9553
  • master default
  • cgnsUnstructured
  • partitioning
  • poppler
  • HighOrderBLCurving
  • gmsh_3_0_4
  • gmsh_3_0_3
  • gmsh_3_0_2
  • gmsh_3_0_1
  • gmsh_3_0_0
  • gmsh_2_16_0
  • gmsh_2_15_0
  • gmsh_2_14_1
  • gmsh_2_14_0
  • gmsh_2_13_2
  • gmsh_2_13_1
  • gmsh_2_12_0
  • gmsh_2_11_0
  • gmsh_2_10_1
  • gmsh_2_10_0
  • gmsh_2_9_3
  • gmsh_2_9_2
  • gmsh_2_9_1
  • gmsh_2_9_0
  • gmsh_2_8_6
26 results

memory.c

Blame
  • Forked from gmsh / gmsh
    Source project has a limited visibility.
    graph.c 15.01 KiB
    /*
     * Copyright 1997, Regents of the University of Minnesota
     *
     * graph.c
     *
     * This file contains functions that deal with setting up the graphs
     * for METIS.
     *
     * Started 7/25/97
     * George
     *
     * $Id: graph.c,v 1.1 2005-09-07 14:36:45 remacle Exp $
     *
     */
    
    #include <metis.h>
    
    /*************************************************************************
    * This function sets up the graph from the user input
    **************************************************************************/
    void SetUpGraph(GraphType *graph, int OpType, int nvtxs, int ncon,
           idxtype *xadj, idxtype *adjncy, idxtype *vwgt, idxtype *adjwgt, int wgtflag)
    {
      int i, j, k, sum, gsize;
      float *nvwgt;
      idxtype tvwgt[MAXNCON];
    
      if (OpType == OP_KMETIS && ncon == 1 && (wgtflag&2) == 0 && (wgtflag&1) == 0) {
        SetUpGraphKway(graph, nvtxs, xadj, adjncy);
        return;
      }
    
      InitGraph(graph);
    
      graph->nvtxs = nvtxs;
      graph->nedges = xadj[nvtxs];
      graph->ncon = ncon;
      graph->xadj = xadj;
      graph->adjncy = adjncy;
    
      if (ncon == 1) { /* We are in the non mC mode */
        gsize = 0; 
        if ((wgtflag&2) == 0)
          gsize += nvtxs;
        if ((wgtflag&1) == 0)
          gsize += graph->nedges;
    
        gsize += 2*nvtxs;
    
        graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata");
    
        /* Create the vertex/edge weight vectors if they are not supplied */
        gsize = 0;
        if ((wgtflag&2) == 0) {
          vwgt = graph->vwgt = idxset(nvtxs, 1, graph->gdata);
          gsize += nvtxs;
        }
        else
          graph->vwgt = vwgt;
    
        if ((wgtflag&1) == 0) {
          adjwgt = graph->adjwgt = idxset(graph->nedges, 1, graph->gdata+gsize);
          gsize += graph->nedges;
        }
        else
          graph->adjwgt = adjwgt;
    
    
        /* Compute the initial values of the adjwgtsum */
        graph->adjwgtsum = graph->gdata + gsize;
        gsize += nvtxs;
    
        for (i=0; i<nvtxs; i++) {
          sum = 0;
          for (j=xadj[i]; j<xadj[i+1]; j++)
            sum += adjwgt[j];
          graph->adjwgtsum[i] = sum;
        }
    
        graph->cmap = graph->gdata + gsize;
        gsize += nvtxs;
    
      }
      else {  /* Set up the graph in MOC mode */
        gsize = 0; 
        if ((wgtflag&1) == 0)
          gsize += graph->nedges;
    
        gsize += 2*nvtxs;
    
        graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata");
        gsize = 0;
    
        for (i=0; i<ncon; i++) 
          tvwgt[i] = idxsum_strd(nvtxs, vwgt+i, ncon);
        
        nvwgt = graph->nvwgt = fmalloc(ncon*nvtxs, "SetUpGraph: nvwgt");
    
        for (i=0; i<nvtxs; i++) {
          for (j=0; j<ncon; j++) 
            nvwgt[i*ncon+j] = (1.0*vwgt[i*ncon+j])/(1.0*tvwgt[j]);
        }
    
    
        /* Create the edge weight vectors if they are not supplied */
        if ((wgtflag&1) == 0) {
          adjwgt = graph->adjwgt = idxset(graph->nedges, 1, graph->gdata+gsize);
          gsize += graph->nedges;
        }
        else
          graph->adjwgt = adjwgt;
    
        /* Compute the initial values of the adjwgtsum */
        graph->adjwgtsum = graph->gdata + gsize;
        gsize += nvtxs;
    
        for (i=0; i<nvtxs; i++) {
          sum = 0;
          for (j=xadj[i]; j<xadj[i+1]; j++)
            sum += adjwgt[j];
          graph->adjwgtsum[i] = sum;
        }
    
        graph->cmap = graph->gdata + gsize;
        gsize += nvtxs;
    
      }
    
      if (OpType != OP_KMETIS && OpType != OP_KVMETIS) {
        graph->label = idxmalloc(nvtxs, "SetUpGraph: label");
    
        for (i=0; i<nvtxs; i++)
          graph->label[i] = i;
      }
    
    }
    
    
    /*************************************************************************
    * This function sets up the graph from the user input
    **************************************************************************/
    void SetUpGraphKway(GraphType *graph, int nvtxs, idxtype *xadj, idxtype *adjncy)
    {
      int i;
    
      InitGraph(graph);
    
      graph->nvtxs = nvtxs;
      graph->nedges = xadj[nvtxs];
      graph->ncon = 1;
      graph->xadj = xadj;
      graph->vwgt = NULL;
      graph->adjncy = adjncy;
      graph->adjwgt = NULL;
    
      graph->gdata = idxmalloc(2*nvtxs, "SetUpGraph: gdata");
      graph->adjwgtsum = graph->gdata;
      graph->cmap = graph->gdata + nvtxs;
    
      /* Compute the initial values of the adjwgtsum */
      for (i=0; i<nvtxs; i++) 
        graph->adjwgtsum[i] = xadj[i+1]-xadj[i];
    
    }
    
    
    
    /*************************************************************************
    * This function sets up the graph from the user input
    **************************************************************************/
    void SetUpGraph2(GraphType *graph, int nvtxs, int ncon, idxtype *xadj, 
           idxtype *adjncy, float *nvwgt, idxtype *adjwgt)
    {
      int i, j, sum;
    
      InitGraph(graph);
    
      graph->nvtxs = nvtxs;
      graph->nedges = xadj[nvtxs];
      graph->ncon = ncon;
      graph->xadj = xadj;
      graph->adjncy = adjncy;
      graph->adjwgt = adjwgt;
    
      graph->nvwgt = fmalloc(nvtxs*ncon, "SetUpGraph2: graph->nvwgt");
      scopy(nvtxs*ncon, nvwgt, graph->nvwgt);
    
      graph->gdata = idxmalloc(2*nvtxs, "SetUpGraph: gdata");
    
      /* Compute the initial values of the adjwgtsum */
      graph->adjwgtsum = graph->gdata;
      for (i=0; i<nvtxs; i++) {
        sum = 0;
        for (j=xadj[i]; j<xadj[i+1]; j++)
          sum += adjwgt[j];
        graph->adjwgtsum[i] = sum;
      }
    
      graph->cmap = graph->gdata+nvtxs;
    
      graph->label = idxmalloc(nvtxs, "SetUpGraph: label");
      for (i=0; i<nvtxs; i++)
        graph->label[i] = i;
    
    }
    
    
    /*************************************************************************
    * This function sets up the graph from the user input
    **************************************************************************/
    void VolSetUpGraph(GraphType *graph, int OpType, int nvtxs, int ncon, idxtype *xadj, 
                       idxtype *adjncy, idxtype *vwgt, idxtype *vsize, int wgtflag)
    {
      int i, j, k, sum, gsize;
      idxtype *adjwgt;
      float *nvwgt;
      idxtype tvwgt[MAXNCON];
    
      InitGraph(graph);
    
      graph->nvtxs = nvtxs;
      graph->nedges = xadj[nvtxs];
      graph->ncon = ncon;
      graph->xadj = xadj;
      graph->adjncy = adjncy;
    
      if (ncon == 1) { /* We are in the non mC mode */
        gsize = graph->nedges;  /* This is for the edge weights */
        if ((wgtflag&2) == 0)
          gsize += nvtxs; /* vwgts */
        if ((wgtflag&1) == 0)
          gsize += nvtxs; /* vsize */
    
        gsize += 2*nvtxs;
    
        graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata");
    
        /* Create the vertex/edge weight vectors if they are not supplied */
        gsize = 0;
        if ((wgtflag&2) == 0) {
          vwgt = graph->vwgt = idxset(nvtxs, 1, graph->gdata);
          gsize += nvtxs;
        }
        else
          graph->vwgt = vwgt;
    
        if ((wgtflag&1) == 0) {
          vsize = graph->vsize = idxset(nvtxs, 1, graph->gdata);
          gsize += nvtxs;
        }
        else
          graph->vsize = vsize;
    
        /* Allocate memory for edge weights and initialize them to the sum of the vsize */
        adjwgt = graph->adjwgt = graph->gdata+gsize;
        gsize += graph->nedges;
    
        for (i=0; i<nvtxs; i++) {
          for (j=xadj[i]; j<xadj[i+1]; j++)
            adjwgt[j] = 1+vsize[i]+vsize[adjncy[j]];
        }
    
    
        /* Compute the initial values of the adjwgtsum */
        graph->adjwgtsum = graph->gdata + gsize;
        gsize += nvtxs;
    
        for (i=0; i<nvtxs; i++) {
          sum = 0;
          for (j=xadj[i]; j<xadj[i+1]; j++)
            sum += adjwgt[j];
          graph->adjwgtsum[i] = sum;
        }
    
        graph->cmap = graph->gdata + gsize;
        gsize += nvtxs;
    
      }
      else {  /* Set up the graph in MOC mode */
        gsize = graph->nedges; 
        if ((wgtflag&1) == 0)
          gsize += nvtxs;
    
        gsize += 2*nvtxs;
    
        graph->gdata = idxmalloc(gsize, "SetUpGraph: gdata");
        gsize = 0;
    
        /* Create the normalized vertex weights along each constrain */
        if ((wgtflag&2) == 0) 
          vwgt = idxsmalloc(nvtxs, 1, "SetUpGraph: vwgt");
    
        for (i=0; i<ncon; i++) 
          tvwgt[i] = idxsum_strd(nvtxs, vwgt+i, ncon);
        
        nvwgt = graph->nvwgt = fmalloc(ncon*nvtxs, "SetUpGraph: nvwgt");
    
        for (i=0; i<nvtxs; i++) {
          for (j=0; j<ncon; j++) 
            nvwgt[i*ncon+j] = (1.0*vwgt[i*ncon+j])/(1.0*tvwgt[j]);
        }
        if ((wgtflag&2) == 0) 
          free(vwgt);
    
    
        /* Create the vsize vector if it is not supplied */
        if ((wgtflag&1) == 0) {
          vsize = graph->vsize = idxset(nvtxs, 1, graph->gdata);
          gsize += nvtxs;
        }
        else
          graph->vsize = vsize;
    
        /* Allocate memory for edge weights and initialize them to the sum of the vsize */
        adjwgt = graph->adjwgt = graph->gdata+gsize;
        gsize += graph->nedges;
    
        for (i=0; i<nvtxs; i++) {
          for (j=xadj[i]; j<xadj[i+1]; j++)
            adjwgt[j] = 1+vsize[i]+vsize[adjncy[j]];
        }
    
        /* Compute the initial values of the adjwgtsum */
        graph->adjwgtsum = graph->gdata + gsize;
        gsize += nvtxs;
    
        for (i=0; i<nvtxs; i++) {
          sum = 0;
          for (j=xadj[i]; j<xadj[i+1]; j++)
            sum += adjwgt[j];
          graph->adjwgtsum[i] = sum;
        }
    
        graph->cmap = graph->gdata + gsize;
        gsize += nvtxs;
    
      }
    
      if (OpType != OP_KVMETIS) {
        graph->label = idxmalloc(nvtxs, "SetUpGraph: label");
    
        for (i=0; i<nvtxs; i++)
          graph->label[i] = i;
      }
    
    }
    
    
    /*************************************************************************
    * This function randomly permutes the adjacency lists of a graph
    **************************************************************************/
    void RandomizeGraph(GraphType *graph)
    {
      int i, j, k, l, tmp, nvtxs;
      idxtype *xadj, *adjncy, *adjwgt;
    
      nvtxs = graph->nvtxs;
      xadj = graph->xadj;
      adjncy = graph->adjncy;
      adjwgt = graph->adjwgt;
    
      for (i=0; i<nvtxs; i++) {
        l = xadj[i+1]-xadj[i];
        for (j=xadj[i]; j<xadj[i+1]; j++) {
          k = xadj[i] + RandomInRange(l);
          SWAP(adjncy[j], adjncy[k], tmp);
          SWAP(adjwgt[j], adjwgt[k], tmp);
        }
      }
    }
    
    
    /*************************************************************************
    * This function checks whether or not partition pid is contigous
    **************************************************************************/
    int IsConnectedSubdomain(CtrlType *ctrl, GraphType *graph, int pid, int report)
    {
      int i, j, k, nvtxs, first, last, nleft, ncmps, wgt;
      idxtype *xadj, *adjncy, *where, *touched, *queue;
      idxtype *cptr;
    
      nvtxs = graph->nvtxs;
      xadj = graph->xadj;
      adjncy = graph->adjncy;
      where = graph->where;
    
      touched = idxsmalloc(nvtxs, 0, "IsConnected: touched");
      queue = idxmalloc(nvtxs, "IsConnected: queue");
      cptr = idxmalloc(nvtxs, "IsConnected: cptr");
    
      nleft = 0;
      for (i=0; i<nvtxs; i++) {
        if (where[i] == pid) 
          nleft++;
      }
    
      for (i=0; i<nvtxs; i++) {
        if (where[i] == pid) 
          break;
      }
    
      touched[i] = 1;
      queue[0] = i;
      first = 0; last = 1;
    
      cptr[0] = 0;  /* This actually points to queue */
      ncmps = 0;
      while (first != nleft) {
        if (first == last) { /* Find another starting vertex */
          cptr[++ncmps] = first;
          for (i=0; i<nvtxs; i++) {
            if (where[i] == pid && !touched[i])
              break;
          }
          queue[last++] = i;
          touched[i] = 1;
        }
    
        i = queue[first++];
        for (j=xadj[i]; j<xadj[i+1]; j++) {
          k = adjncy[j];
          if (where[k] == pid && !touched[k]) {
            queue[last++] = k;
            touched[k] = 1;
          }
        }
      }
      cptr[++ncmps] = first;
    
      if (ncmps > 1 && report) {
        printf("The graph has %d connected components in partition %d:\t", ncmps, pid);
        for (i=0; i<ncmps; i++) {
          wgt = 0;
          for (j=cptr[i]; j<cptr[i+1]; j++)
            wgt += graph->vwgt[queue[j]];
          printf("[%5d %5d] ", cptr[i+1]-cptr[i], wgt);
          /*
          if (cptr[i+1]-cptr[i] == 1)
            printf("[%d %d] ", queue[cptr[i]], xadj[queue[cptr[i]]+1]-xadj[queue[cptr[i]]]);
          */
        }
        printf("\n");
      }
    
      GKfree(&touched, &queue, &cptr, LTERM);
    
      return (ncmps == 1 ? 1 : 0);
    }
    
    
    /*************************************************************************
    * This function checks whether a graph is contigous or not
    **************************************************************************/
    int IsConnected(CtrlType *ctrl, GraphType *graph, int report)
    {
      int i, j, k, nvtxs, first, last;
      idxtype *xadj, *adjncy, *touched, *queue;
    
      nvtxs = graph->nvtxs;
      xadj = graph->xadj;
      adjncy = graph->adjncy;
    
      touched = idxsmalloc(nvtxs, 0, "IsConnected: touched");
      queue = idxmalloc(nvtxs, "IsConnected: queue");
    
      touched[0] = 1;
      queue[0] = 0;
      first = 0; last = 1;
    
      while (first < last) {
        i = queue[first++];
        for (j=xadj[i]; j<xadj[i+1]; j++) {
          k = adjncy[j];
          if (!touched[k]) {
            queue[last++] = k;
            touched[k] = 1;
          }
        }
      }
    
      if (first != nvtxs && report)
        printf("The graph is not connected. It has %d disconnected vertices!\n", nvtxs-first);
    
      return (first == nvtxs ? 1 : 0);
    }
    
    
    /*************************************************************************
    * This function checks whether or not partition pid is contigous
    **************************************************************************/
    int IsConnected2(GraphType *graph, int report)
    {
      int i, j, k, nvtxs, first, last, nleft, ncmps, wgt;
      idxtype *xadj, *adjncy, *where, *touched, *queue;
      idxtype *cptr;
    
      nvtxs = graph->nvtxs;
      xadj = graph->xadj;
      adjncy = graph->adjncy;
      where = graph->where;
    
      touched = idxsmalloc(nvtxs, 0, "IsConnected: touched");
      queue = idxmalloc(nvtxs, "IsConnected: queue");
      cptr = idxmalloc(nvtxs, "IsConnected: cptr");
    
      nleft = nvtxs;
      touched[0] = 1;
      queue[0] = 0;
      first = 0; last = 1;
    
      cptr[0] = 0;  /* This actually points to queue */
      ncmps = 0;
      while (first != nleft) {
        if (first == last) { /* Find another starting vertex */
          cptr[++ncmps] = first;
          for (i=0; i<nvtxs; i++) {
            if (!touched[i])
              break;
          }
          queue[last++] = i;
          touched[i] = 1;
        }
    
        i = queue[first++];
        for (j=xadj[i]; j<xadj[i+1]; j++) {
          k = adjncy[j];
          if (!touched[k]) {
            queue[last++] = k;
            touched[k] = 1;
          }
        }
      }
      cptr[++ncmps] = first;
    
      if (ncmps > 1 && report) {
        printf("%d connected components:\t", ncmps);
        for (i=0; i<ncmps; i++) {
          if (cptr[i+1]-cptr[i] > 200)
            printf("[%5d] ", cptr[i+1]-cptr[i]);
        }
        printf("\n");
      }
    
      GKfree(&touched, &queue, &cptr, LTERM);
    
      return (ncmps == 1 ? 1 : 0);
    }
    
    
    /*************************************************************************
    * This function returns the number of connected components in cptr,cind
    * The separator of the graph is used to split it and then find its components.
    **************************************************************************/
    int FindComponents(CtrlType *ctrl, GraphType *graph, idxtype *cptr, idxtype *cind)
    {
      int i, j, k, nvtxs, first, last, nleft, ncmps, wgt;
      idxtype *xadj, *adjncy, *where, *touched, *queue;
    
      nvtxs = graph->nvtxs;
      xadj = graph->xadj;
      adjncy = graph->adjncy;
      where = graph->where;
    
      touched = idxsmalloc(nvtxs, 0, "IsConnected: queue");
    
      for (i=0; i<graph->nbnd; i++)
        touched[graph->bndind[i]] = 1;
    
      queue = cind;
    
      nleft = 0;
      for (i=0; i<nvtxs; i++) {
        if (where[i] != 2) 
          nleft++;
      }
    
      for (i=0; i<nvtxs; i++) {
        if (where[i] != 2)
          break;
      }
    
      touched[i] = 1;
      queue[0] = i;
      first = 0; last = 1;
    
      cptr[0] = 0;  /* This actually points to queue */
      ncmps = 0;
      while (first != nleft) {
        if (first == last) { /* Find another starting vertex */
          cptr[++ncmps] = first;
          for (i=0; i<nvtxs; i++) {
            if (!touched[i])
              break;
          }
          queue[last++] = i;
          touched[i] = 1;
        }
    
        i = queue[first++];
        for (j=xadj[i]; j<xadj[i+1]; j++) {
          k = adjncy[j];
          if (!touched[k]) {
            queue[last++] = k;
            touched[k] = 1;
          }
        }
      }
      cptr[++ncmps] = first;
    
      free(touched);
    
      return ncmps;
    }