📄 cuthill.cpp
字号:
// does Cuthill-McKee algorithm as described in Hoole;
#include<stdafx.h>
#include<afxtempl.h>
#include<stdio.h>
#include<math.h>
#include "fkn.h"
#include "fknDlg.h"
#include "complex.h"
#include "mesh.h"
#include "spars.h"
#include "FemmeDocCore.h"
#define muo 1.2566370614359173e-6
BOOL CFemmeDocCore::Cuthill()
{
FILE *fp;
int i,j,k,n0,n1,n;
int newwide,*newnum,**ocon;
int *numcon,*nxtnum;
CNode swap;
char infile[256];
// allocate storage
nxtnum=(int *)calloc(NumNodes,sizeof(int));
newnum=(int *)calloc(NumNodes,sizeof(int));
numcon=(int *)calloc(NumNodes,sizeof(int));
ocon=(int **)calloc(NumNodes,sizeof(int *));
// initialize node array;
for(i=0;i<NumNodes;i++) newnum[i]= -1;
// read in connectivity from nodefile
sprintf(infile,"%s.edge",PathName);
if((fp=fopen(infile,"rt"))==NULL)
{
MsgBox("Couldn't open %s",infile);
return FALSE;
}
fscanf(fp,"%i",&k); // read in number of lines
fscanf(fp,"%i",&j); // read in boundarymarker flag;
// allocate space for connections;
ocon[0]=(int *)calloc(2*k,sizeof(int));
// with first pass, figure out how many connections
// there are for each node;
for(i=0;i<k;i++)
{
fscanf(fp,"%i",&j);
fscanf(fp,"%i",&n0);
fscanf(fp,"%i",&n1);
fscanf(fp,"%i",&j);
numcon[n0]++;
numcon[n1]++;
}
// mete out connection storage space;
for(i=1,n=0;i<NumNodes;i++)
{
n+=numcon[i-1];
ocon[i]=ocon[0]+n;
}
// on second pass through file, store connections;
rewind(fp);
fscanf(fp,"%li",&k); // read in number of lines
fscanf(fp,"%li",&j); // read in boundarymarker flag;
for(i=0;i<k;i++)
{
fscanf(fp,"%i",&j);
fscanf(fp,"%i",&n0);
fscanf(fp,"%i",&n1);
fscanf(fp,"%i",&j);
ocon[n0][nxtnum[n0]]=n1; nxtnum[n0]++;
ocon[n1][nxtnum[n1]]=n0; nxtnum[n1]++;
}
fclose(fp);
DeleteFile(infile);
// sort connections in order of increasing connectivity;
// I'm lazy, so I'm doing a bubble sort;
for(n0=0;n0<NumNodes;n0++)
{
for(i=1;i<numcon[n0];i++)
for(j=1;j<numcon[n0];j++)
if(numcon[ocon[n0][j]]<numcon[ocon[n0][j-1]])
{
n1=ocon[n0][j];
ocon[n0][j]=ocon[n0][j-1];
ocon[n0][j-1]=n1;
}
}
// search for a node to start with;
j=numcon[0]; n0=0;
for(i=1;i<NumNodes;i++){
if(numcon[i]<j){
j=numcon[i];
n0=i;
}
if(j==2) i=k; // break out if j==2,
// because this is the best we can do
}
// do renumbering algorithm;
for(i=0;i<NumNodes;i++) nxtnum[i]=-1;
newnum[n0]=0; n=1; nxtnum[0]=n0;
do{
// renumber in order of increasing number of connections;
for(i=0;i<numcon[n0];i++)
{
if (newnum[ocon[n0][i]]<0)
{
newnum[ocon[n0][i]]=n;
nxtnum[n]=ocon[n0][i];
n++;
}
}
// need to catch case in which problem is multiply
// connected and still renumber right.
if(nxtnum[newnum[n0]+1]<0){
// AfxMessageBox("Multiply Connected!");
// exit(0);
// first, get a node that hasn't been visited yet;
for(i=0;i<NumNodes;i++)
if(newnum[i]<0){
j=numcon[i];
n0=i;
i=NumNodes;
}
// now, get a new starting node;
for(i=0;i<NumNodes;i++)
{
if((newnum[i]<0) && (numcon[i]<j))
{
j=numcon[i];
n0=i;
}
if(j==2) i=NumNodes; // break out if j==2,
// because this is the
// best we can do
}
// now, set things to restart;
newnum[n0]=n;
nxtnum[n]=n0;
n++;
}
else n0=nxtnum[newnum[n0]+1];
} while(n<NumNodes);
// remap connectivities;
for(i=0;i<NumNodes;i++)
for(j=0;j<numcon[i];j++)
ocon[i][j]=newnum[ocon[i][j]];
// remap (anti)periodic boundary points
for(i=0;i<NumPBCs;i++)
{
pbclist[i].x=newnum[pbclist[i].x];
pbclist[i].y=newnum[pbclist[i].y];
}
// find new bandwidth;
// PBCs fuck up the banding, som could have to do
// something like:
// if(NumPBCs!=0) BandWidth=0;
// else{
// but if we apply the PCBs the last thing before the
// solver is called, we can take advantage of banding
// speed optimizations without messing things up.
for(n0=0,newwide=0;n0<NumNodes;n0++)
{
for(i=0;i<numcon[n0];i++)
if(abs(newnum[n0]-ocon[n0][i])>newwide)
{
newwide=abs(newnum[n0]-ocon[n0][i]);
}
}
BandWidth=newwide+1;
// }
// free up the variables that we needed during the routine....
free(numcon);
free(nxtnum);
free(ocon[0]);
free(ocon);
// new mapping remains in newnum;
// apply this mapping to elements first.
for(i=0;i<NumEls;i++)
for(j=0;j<3;j++)
meshele[i].p[j]=newnum[meshele[i].p[j]];
// now, sort nodes based on newnum;
for(i=0;i<NumNodes;i++)
while(newnum[i]!=i)
{
j=newnum[i];
n=newnum[j]; newnum[j]=newnum[i]; newnum[i]=n;
swap=meshnode[j]; meshnode[j]=meshnode[i]; meshnode[i]=swap;
}
free(newnum);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -