⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 graph.c

📁 cfd求解器使用与gmsh网格的求解
💻 C
字号:
#define RCSID "$Id: Graph.c,v 1.3 2006/02/26 00:42:52 geuzaine Exp $"/* * Copyright (C) 1997-2006 P. Dular, C. Geuzaine * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * * Please report all bugs and problems to <getdp@geuz.org>. * * Contributor(s): *   David Colignon */#include "GetDP.h"#include "Graph.h"#include "DofData.h"#include "Compat.h"/*  Si on est sur d'utiliser Metis tout le temps, on devrait definir   correctement la strcture de Graphe avec idxtype*//* ------------------------------------------------------------------------ *//*  private functions                                                       *//* ------------------------------------------------------------------------ */static int Graph_cmpij(int ai,int aj,int bi,int bj){  if(ai<bi) return -1;  if(ai>bi) return 1;  if(aj<bj) return -1;  if(aj>bj) return 1;  return 0;}static int *alloc_ivec(long nl, long nh){  int *v;    v=(int *)Malloc((size_t) ((nh-nl+1+1)*sizeof(int)));  return v-nl+1;}static void free_ivec(int *v, long nl, long nh){  Free(v+nl-1);}#define SWAP(a,b)  temp=(a);(a)=(b);(b)=temp;#define SWAPI(a,b) tempi=(a);(a)=(b);(b)=tempi;#define M          7#define NSTACK     50#define M1        -1static void Graph_sort(unsigned long n, int ai[] , int aj []){  unsigned long i,ir=n,j,k,l=1;  int *istack,jstack=0,tempi;  int    b,c;  GetDP_Begin("Graph_sort");      istack=alloc_ivec(1,NSTACK);  for (;;) {    if (ir-l < M) {      for (j=l+1;j<=ir;j++) {	b=ai[j M1];	c=aj[j M1];	for (i=j-1;i>=1;i--) {	  if (Graph_cmpij(ai[i M1],aj[i M1],b,c) <= 0) break;	  ai[i+1 M1]=ai[i M1];	  aj[i+1 M1]=aj[i M1];	}	ai[i+1 M1]=b;	aj[i+1 M1]=c;      }      if (!jstack) {	free_ivec(istack,1,NSTACK);	GetDP_End;      }      ir=istack[jstack];      l=istack[jstack-1];      jstack -= 2;    }     else {      k=(l+ir) >> 1;      SWAPI(ai[k M1],ai[l+1 M1])      SWAPI(aj[k M1],aj[l+1 M1])      if (Graph_cmpij(ai[l+1 M1],aj[l+1 M1],ai[ir M1],aj[ir M1])>0){	SWAPI(ai[l+1 M1],ai[ir M1])	SWAPI(aj[l+1 M1],aj[ir M1])      }      if (Graph_cmpij(ai[l M1],aj[l M1],ai[ir M1],aj[ir M1])>0){	SWAPI(ai[l M1],ai[ir M1])	SWAPI(aj[l M1],aj[ir M1])      }      if (Graph_cmpij(ai[l+1 M1],aj[l+1 M1],ai[l M1],aj[l M1])>0){	SWAPI(ai[l+1 M1],ai[l M1])	SWAPI(aj[l+1 M1],aj[l M1])      }      i=l+1;      j=ir;      b=ai[l M1];      c=aj[l M1];      for (;;) {	do i++; while (Graph_cmpij(ai[i M1],aj[i M1],b,c) < 0);	do j--; while (Graph_cmpij(ai[j M1],aj[j M1],b,c) > 0);	if (j < i) break;	SWAPI(ai[i M1],ai[j M1])	SWAPI(aj[i M1],aj[j M1])	}      ai[l M1]=ai[j M1];      ai[j M1]=b;      aj[l M1]=aj[j M1];      aj[j M1]=c;      jstack += 2;      if (jstack > NSTACK) {	Msg(GERROR, "NSTACK too small in sort2");      }      if (ir-i+1 >= j-l) {	istack[jstack]=ir;	istack[jstack-1]=i;	ir=j-1;      }       else {	istack[jstack]=j-1;	istack[jstack-1]=l;	l=i;      }    }  }  GetDP_End ;}#undef M#undef NSTACK#undef SWAP#undef SWAPI#undef M1static void Graph_deblign (int nz , int *ptr , int *jptr , int *ai){  int i,ilign;  GetDP_Begin("Graph_deblign");  ilign = 1;  jptr[0] = 1;  for(i=1; i<nz; i++) {    if (ai[i-1] < ai[i]) {      jptr[ilign++]=i+1;      ai[i-1] = 0;    }        else{      ai[i-1] = i+1;    }  }  ai[nz-1] = 0;  GetDP_End ;}void Graph_csr_format (gGraph *GG, int N){  int    i,*ptr,*jptr,*ai,n,iptr,iptr2;  GetDP_Begin("Graph_csr_format");  ptr  = (int*)GG->ptr->array;  jptr = (int*)GG->jptr->array;  ai   = (int*)GG->ai->array;  n    = N;  for(i=0;i<n;i++){    iptr = jptr[i];    while(iptr){      iptr2 = iptr - 1;      iptr = ptr[iptr2];      ptr[iptr2] = i+1;    }  }  Graph_sort(List_Nbr(GG->ai),ai,ptr);  Graph_deblign(List_Nbr(GG->ai),ptr,jptr,ai);  jptr[N]=List_Nbr(GG->ai)+1;  GetDP_End ;} void Graph_restore_format (gGraph *GG){      char *temp;  GetDP_Begin("Graph_restore_format");  temp  = GG->ptr->array;  GG->ptr->array = GG->ai->array;  GG->ai->array = temp;  GetDP_End ;} /* ------------------------------------------------------------------------ *//*  public functions                                                        *//* ------------------------------------------------------------------------ */void InitGraph (int NbLines, gGraph *G){  int i, j=0;  GetDP_Begin("InitGraph");  G->ai   = List_Create (NbLines, NbLines, sizeof(int));  G->ptr  = List_Create (NbLines, NbLines, sizeof(int));  G->jptr = List_Create (NbLines+1, NbLines, sizeof(int));   /* '+1' indispensable: csr_format ecrit 'nnz+1' dans jptr[NbLine] */  for(i=0; i<NbLines; i++) List_Add (G->jptr, &j);  GetDP_End ;}/* attention a la transposition ! */void AddEdgeInGraph (gGraph *G, int ic, int il){  int     *ai, *pp, n, iptr, iptr2, jptr, *ptr, zero = 0;  GetDP_Begin("AddEdgeInGraph");  il--;  pp  = (int*) G->jptr->array;  ptr = (int*) G->ptr->array;  ai  = (int*) G->ai->array;    iptr = pp[il];  iptr2 = iptr-1;    while(iptr>0){    iptr2 = iptr-1;    jptr = ai[iptr2];    if(jptr == ic){      GetDP_End;    }    iptr = ptr[iptr2];  }    List_Add (G->ai, &ic);  List_Add (G->ptr, &zero);    /* Les pointeurs ont pu etre modifies s'il y a eu une reallocation dans List_Add */    ptr = (int*) G->ptr->array;  ai  = (int*) G->ai->array;    n = List_Nbr(G->ai);  if(!pp[il]) pp[il] = n;  else ptr[iptr2] = n;  GetDP_End ;}#if defined(HAVE_METIS)EXTERN_C_BEGIN#include "metis.h"EXTERN_C_ENDvoid PartitionGraph(struct DofData * DofData_P, int NbPartition){  int  i;  int  n9, wgtflag9, numflag9, options9[5];  int  edgecut9;  int  *part_P, *cptr_P, *start_P;  /*  int  kd, kf, kk, cptr, options8[8] ;   int  *ia, *ja, *ia_N, *ja_N, trente=30, zero=0, trenteetun=31, trentedeux=32; */  idxtype *xadj9, *adjncy9, *part9, *perm9, *iperm9;  struct Dof  * Dof_P ;  GetDP_Begin("PartitionGraph");  Graph_csr_format (&DofData_P->Graph, List_Nbr(DofData_P->Graph.jptr));  Graph_restore_format (&DofData_P->Graph);  n9 = List_Nbr(DofData_P->Graph.jptr);  /*    ia = (int*) DofData_P->Graph.jptr->array;    ja = (int*) DofData_P->Graph.ai->array;      psplot_(&n9, ja, ia, &trente, &zero);  */  xadj9 = (idxtype*) DofData_P->Graph.jptr->array;  adjncy9 = (idxtype*) DofData_P->Graph.ai->array;    numflag9 = 1;  perm9 =  (idxtype*) Malloc( n9 * sizeof(idxtype));  iperm9 = (idxtype*) Malloc( n9 * sizeof(idxtype));  /* si Flag_PAR = 1, on n'arrive meme pas jusqu'ici car if (Flag_PAR > 1) dans SolvingAnalyse    if ( NbPartition == 1 ) {    options8[0] = 0 ;    METIS_NodeND( &n9, xadj9, adjncy9, &numflag9, options8, perm9, iperm9);    Msg(PETSC, "METIS Renumbering done") ;       DofData_P->NbrPart = NbPartition ;    DofData_P->Part[0] = 1  ;    DofData_P->Part[1] = DofData_P->NbrDof+1 ;    }    else {  */    wgtflag9 = 0;    options9[0] = 0;    part9 = (idxtype*) Malloc( n9 * sizeof(idxtype));    METIS_PartGraphRecursive( &n9, xadj9, adjncy9, NULL, NULL, 			      &wgtflag9, &numflag9, &NbPartition, options9, &edgecut9, part9);    Msg(PETSC, "METIS partitionning done (edgecut = %d)", edgecut9) ;    Free(adjncy9);    part_P  = (int*) Malloc( (NbPartition) * sizeof(int));    cptr_P  = (int*) Malloc( (NbPartition) * sizeof(int));    for ( i = 1 ; i <= NbPartition ; i++ ) {      part_P[i-1] = 0; /* Taille de la partition */      cptr_P[i-1] = 0;    }    for ( i = 1 ; i <= n9 ; i++ ) {      part_P[part9[i-1]-1]++;      iperm9[i-1] = 0;    }    start_P = (int*) Malloc( (NbPartition) * sizeof(int));    start_P[0] = 0;    for ( i = 2 ; i <= NbPartition ; i++ ) start_P[i-1] = start_P[i-1-1]+part_P[i-1-1];    for ( i = 1 ; i <= n9 ; i++ ) {      cptr_P[part9[i-1]-1]++;      iperm9[i-1] = start_P[part9[i-1]-1]+cptr_P[part9[i-1]-1];      perm9[iperm9[i-1]-1] = i;    }    Free(part9);    Free(cptr_P);    DofData_P->NbrPart = NbPartition ;    for (i=1 ; i <= NbPartition ; i++) {      DofData_P->Part[i-1] = start_P[i-1]+1  ;      Msg(PETSC, "Partition %d: length = %d ",i,part_P[i-1]);    }    DofData_P->Part[NbPartition] = DofData_P->NbrDof+1 ;    Free(part_P);    Free(start_P);    /*   }    */  /* Si on veut imprimer le masque de la matrice, il faut retrier le graphe ...     ia_N = (int*) Malloc( (n9+1) * sizeof(int));     ja_N = (int*) Malloc( (List_Nbr(DofData_P->Graph.ai)) * sizeof(int));     cptr = 1 ;     for (i = 1 ; i <= n9 ; i++) {       ia_N[i-1] = cptr;       kd = ia[perm9[i-1]-1];       kf = ia[perm9[i-1]+1-1]-1;       for (kk = 1 ; kk <= (kf-kd+1) ; kk++) {         if (NbPartition == 1 ) ja_N[cptr+kk-1-1] = iperm9[ja[kd+kk-1-1]-1];         else  ja_N[cptr+kk-1-1] = ja[kd+kk-1-1];       }       cptr = cptr+kf-kd+1;     }     ia_N[i-1] = cptr;     psplot_(&n9, ja_N, ia_N, &trenteetun, &zero);   */   for (i = 0 ; i < List_Nbr(DofData_P->DofList) ; i++) {    Dof_P=(struct Dof *) List_Pointer(DofData_P->DofList,i);    switch (Dof_P->Type) {    case DOF_UNKNOWN :       Dof_P->Case.Unknown.NumDof = iperm9[Dof_P->Case.Unknown.NumDof-1];      break;    case DOF_FIXED :    case DOF_FIXEDWITHASSOCIATE :      break;    default :      Msg(GERROR,"Strange stuff in partitioning");      break;    }  }  for(i = 1 ; i<=DofData_P->NbrDof ; i++){    DofData_P->Nnz[i-1] = xadj9[perm9[i-1]-1+1] - xadj9[perm9[i-1]-1] + 1 ;  }  Free(perm9);  Free(iperm9);  Free(xadj9);  /* free le reste */  GetDP_End ;}#elsevoid PartitionGraph(struct DofData * DofData_P, int NbPartition){  GetDP_Begin("PartitionGraph");  Msg(GERROR, "Impossible to partition (GetDP was compiled without Metis)");  GetDP_End ;}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -