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

📄 mmd.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
📖 第 1 页 / 共 2 页
字号:
*       (xadj, adjncy) -- adjacency structure.*    output parameters --*       (head, dfrow, backward) -- degree doubly linked structure.*       qsize -- size of supernode ( initialized to one).*       list -- linked list.*       marker -- marker vector.****************************************************************************/int  mmdint(int neqns, idxtype *xadj, idxtype *adjncy, idxtype *head, idxtype *forward,     idxtype *backward, idxtype *qsize, idxtype *list, idxtype *marker){    int  fnode, ndeg, node;    for ( node = 1; node <= neqns; node++ ) {        head[node] = 0;        qsize[node] = 1;        marker[node] = 0;        list[node] = 0;    };    /* initialize the degree doubly linked lists. */    for ( node = 1; node <= neqns; node++ ) {        ndeg = xadj[node+1] - xadj[node]/* + 1*/;   /* george */        if (ndeg == 0)          ndeg = 1;        fnode = head[ndeg];        forward[node] = fnode;        head[ndeg] = node;        if ( fnode > 0 ) backward[fnode] = node;        backward[node] = -ndeg;    };    return 0;}/***************************************************************************** mmdnum --- multi minimum degree numbering* purpose -- this routine performs the final step in producing*    the permutation and inverse permutation vectors in the*    multiple elimination version of the minimum degree*    ordering algorithm.* input parameters --*     neqns -- number of equations.*     qsize -- size of supernodes at elimination.* updated parameters --*     invp -- inverse permutation vector. on input,*             if qsize[node] = 0, then node has been merged*             into the node -invp[node]; otherwise,*            -invp[node] is its inverse labelling.* output parameters --*     perm -- the permutation vector.****************************************************************************/void mmdnum(int neqns, idxtype *perm, idxtype *invp, idxtype *qsize){  int father, nextf, node, nqsize, num, root;  for ( node = 1; node <= neqns; node++ ) {      nqsize = qsize[node];      if ( nqsize <= 0 ) perm[node] = invp[node];      if ( nqsize > 0 )  perm[node] = -invp[node];  };  /* for each node which has been merged, do the following. */  for ( node = 1; node <= neqns; node++ ) {      if ( perm[node] <= 0 )  {	 /* trace the merged tree until one which has not */         /* been merged, call it root.                    */         father = node;         while ( perm[father] <= 0 )            father = - perm[father];         /* number node after root. */         root = father;         num = perm[root] + 1;         invp[node] = -num;         perm[root] = num;         /* shorten the merged tree. */         father = node;         nextf = - perm[father];         while ( nextf > 0 ) {            perm[father] = -root;            father = nextf;            nextf = -perm[father];         };      };  /* end of -- if ( perm[node] <= 0 ) -- */  }; /* end of -- for ( node = 1; -- */  /* ready to compute perm. */  for ( node = 1; node <= neqns; node++ ) {        num = -invp[node];        invp[node] = num;        perm[num] = node;  };  return;}/***************************************************************************** mmdupd ---- multiple minimum degree update* purpose -- this routine updates the degrees of nodes after a*            multiple elimination step.* input parameters --*    ehead -- the beginning of the list of eliminated nodes*             (i.e., newly formed elements).*    neqns -- number of equations.*    (xadj, adjncy) -- adjacency structure.*    delta -- tolerance value for multiple elimination.*    maxint -- maximum machine representable (short) integer.* updated parameters --*    mdeg -- new minimum degree after degree update.*    (head, forward, backward) -- degree doubly linked structure.*    qsize -- size of supernode.*    list -- marker vector for degree update.*    *tag   -- tag value.****************************************************************************/void mmdupd(int ehead, int neqns, idxtype *xadj, idxtype *adjncy, int delta, int *mdeg,     idxtype *head, idxtype *forward, idxtype *backward, idxtype *qsize, idxtype *list,     idxtype *marker, int maxint,int *tag){ int  deg, deg0, element, enode, fnode, i, iq2, istop,      istart, j, jstop, jstart, link, mdeg0, mtag, nabor,      node, q2head, qxhead;      mdeg0 = *mdeg + delta;      element = ehead;n100:      if ( element <= 0 ) return;      /* for each of the newly formed element, do the following. */      /* reset tag value if necessary.                           */      mtag = *tag + mdeg0;      if ( mtag >= maxint ) {         *tag = 1;         for ( i = 1; i <= neqns; i++ )             if ( marker[i] < maxint ) marker[i] = 0;         mtag = *tag + mdeg0;      };      /* create two linked lists from nodes associated with 'element': */      /* one with two nabors (q2head) in the adjacency structure, and the*/      /* other with more than two nabors (qxhead). also compute 'deg0',*/      /* number of nodes in this element.                              */      q2head = 0;      qxhead = 0;      deg0 = 0;      link =element;n400:      istart = xadj[link];      istop = xadj[link+1] - 1;      for ( i = istart; i <= istop; i++ ) {          enode = adjncy[i];          link = -enode;          if ( enode < 0 )  goto n400;          if ( enode == 0 ) break;          if ( qsize[enode] != 0 ) {             deg0 += qsize[enode];             marker[enode] = mtag;             /*'enode' requires a degree update*/             if ( backward[enode] == 0 ) {                /* place either in qxhead or q2head list. */                if ( forward[enode] != 2 ) {                     list[enode] = qxhead;                     qxhead = enode;                } else {                     list[enode] = q2head;                     q2head = enode;                };             };          }; /* enf of -- if ( qsize[enode] != 0 ) -- */      }; /* end of -- for ( i = istart; -- */      /* for each node in q2 list, do the following. */      enode = q2head;      iq2 = 1;n900:      if ( enode <= 0 ) goto n1500;      if ( backward[enode] != 0 ) goto n2200;      (*tag)++;      deg = deg0;      /* identify the other adjacent element nabor. */      istart = xadj[enode];      nabor = adjncy[istart];      if ( nabor == element ) nabor = adjncy[istart+1];      link = nabor;      if ( forward[nabor] >= 0 ) {           /* nabor is uneliminated, increase degree count. */           deg += qsize[nabor];           goto n2100;      };       /* the nabor is eliminated. for each node in the 2nd element */       /* do the following.                                         */n1000:       istart = xadj[link];       istop = xadj[link+1] - 1;       for ( i = istart; i <= istop; i++ ) {           node = adjncy[i];           link = -node;           if ( node != enode ) {                if ( node < 0 ) goto n1000;                if ( node == 0 )  goto n2100;                if ( qsize[node] != 0 ) {                     if ( marker[node] < *tag ) {                        /* 'node' is not yet considered. */                        marker[node] = *tag;                        deg += qsize[node];                     } else {                        if ( backward[node] == 0 ) {                             if ( forward[node] == 2 ) {                                /* 'node' is indistinguishable from 'enode'.*/                                /* merge them into a new supernode.         */                                qsize[enode] += qsize[node];                                qsize[node] = 0;                                marker[node] = maxint;                                forward[node] = -enode;                                backward[node] = -maxint;                             } else {                                /* 'node' is outmacthed by 'enode' */				if (backward[node]==0) backward[node] = -maxint;                             };                        }; /* end of -- if ( backward[node] == 0 ) -- */                    }; /* end of -- if ( marker[node] < *tag ) -- */                }; /* end of -- if ( qsize[node] != 0 ) -- */              }; /* end of -- if ( node != enode ) -- */          }; /* end of -- for ( i = istart; -- */          goto n2100;n1500:          /* for each 'enode' in the 'qx' list, do the following. */          enode = qxhead;          iq2 = 0;n1600:    if ( enode <= 0 )  goto n2300;          if ( backward[enode] != 0 )  goto n2200;          (*tag)++;          deg = deg0;          /*for each unmarked nabor of 'enode', do the following.*/          istart = xadj[enode];          istop = xadj[enode+1] - 1;          for ( i = istart; i <= istop; i++ ) {                nabor = adjncy[i];                if ( nabor == 0 ) break;                if ( marker[nabor] < *tag ) {                     marker[nabor] = *tag;                     link = nabor;                     if ( forward[nabor] >= 0 )                           /*if uneliminated, include it in deg count.*/                          deg += qsize[nabor];                     else {n1700:                          /* if eliminated, include unmarked nodes in this*/                          /* element into the degree count.             */                          jstart = xadj[link];                          jstop = xadj[link+1] - 1;                          for ( j = jstart; j <= jstop; j++ ) {                                node = adjncy[j];                                link = -node;                                if ( node < 0 ) goto n1700;                                if ( node == 0 ) break;                                if ( marker[node] < *tag ) {                                    marker[node] = *tag;                                    deg += qsize[node];                                };                          }; /* end of -- for ( j = jstart; -- */                     }; /* end of -- if ( forward[nabor] >= 0 ) -- */                  }; /* end of -- if ( marker[nabor] < *tag ) -- */          }; /* end of -- for ( i = istart; -- */n2100:          /* update external degree of 'enode' in degree structure, */          /* and '*mdeg' if necessary.                     */          deg = deg - qsize[enode] + 1;          fnode = head[deg];          forward[enode] = fnode;          backward[enode] = -deg;          if ( fnode > 0 ) backward[fnode] = enode;          head[deg] = enode;          if ( deg < *mdeg ) *mdeg = deg;n2200:          /* get next enode in current element. */          enode = list[enode];          if ( iq2 == 1 ) goto n900;          goto n1600;n2300:          /* get next element in the list. */          *tag = mtag;          element = list[element];          goto n100;    }

⌨️ 快捷键说明

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