stream.c

来自「FreeFem++可以生成高质量的有限元网格。可以用于流体力学」· C语言 代码 · 共 1,962 行 · 第 1/4 页

C
1,962
字号
#include "medit.h"#include "extern.h"#include "sproto.h"#define MAX_PTS   100000#define MAX_CPT   5000#define MAX_LST   1024#define COS175  -0.996194698#define COS178  -0.99939083#define HSIZ     0.03#define EPST    -1.e-14#define EPSR     1.e+14extern int       reftype,refitem;extern GLfloat   altcoef;int    nbar=0;enum   {Euler=1,RK4=2};/* find tetra containg p, starting nsdep */int locateTetra(pMesh mesh,int nsdep,int base,float *p,double *cb) {  pTetra   pt;  pPoint   p0,p1,p2,p3;  double   bx,by,bz,cx,cy,cz,dx,dy,dz,vx,vy,vz,apx,apy,apz;  double   epsra,vol1,vol2,vol3,vol4,dd;   int     *adj,iadr,it,nsfin;  it    = 0;  nsfin = nsdep;  /*  printf("locateTetra: searching for %f %f %f\n",p[0],p[1],p[2]);*/  do {    if ( !nsfin )  return(0);    pt = &mesh->tetra[nsfin];    if ( !pt->v[0] )  return(0);    if ( pt->mark == base )  return(0);    pt->mark = base;    iadr = 4*(nsfin-1)+1;    adj  = &mesh->adja[iadr];    p0 = &mesh->point[pt->v[0]];    p1 = &mesh->point[pt->v[1]];    p2 = &mesh->point[pt->v[2]];    p3 = &mesh->point[pt->v[3]];    /* barycentric */    bx  = p1->c[0] - p0->c[0];    by  = p1->c[1] - p0->c[1];    bz  = p1->c[2] - p0->c[2];    cx  = p2->c[0] - p0->c[0];    cy  = p2->c[1] - p0->c[1];    cz  = p2->c[2] - p0->c[2];    dx  = p3->c[0] - p0->c[0];    dy  = p3->c[1] - p0->c[1];    dz  = p3->c[2] - p0->c[2];    /* test volume */    vx  = cy*dz - cz*dy;    vy  = cz*dx - cx*dz;    vz  = cx*dy - cy*dx;    epsra = EPST*(bx*vx + by*vy + bz*vz);    apx = p[0] - p0->c[0];    apy = p[1] - p0->c[1];    apz = p[2] - p0->c[2];    /* p in 2 */    vol2  = apx*vx + apy*vy + apz*vz;    if ( epsra > vol2 ) {      nsfin = adj[1];      continue;    }    /* p in 3 */    vx  = by*apz - bz*apy;    vy  = bz*apx - bx*apz;    vz  = bx*apy - by*apx;    vol3 = dx*vx + dy*vy + dz*vz;    if ( epsra > vol3 ) {      nsfin = adj[2];      continue;    }        /* p in 4 */    vol4 = -cx*vx - cy*vy - cz*vz;    if ( epsra > vol4 ) {      nsfin = adj[3];      continue;    }        /* p in 1 */    vol1 = -epsra * EPSR - vol2 - vol3 - vol4;    if ( epsra > vol1 ) {      nsfin = adj[0];      continue;    }    dd = vol1+vol2+vol3+vol4;    if ( dd != 0.0 )  dd = 1.0 / dd;    cb[0] = vol1 * dd;    cb[1] = vol2 * dd;    cb[2] = vol3 * dd;    cb[3] = vol4 * dd;         pt->cpt++;    return(nsfin);  }  while ( ++it <= mesh->ntet );  return(0);}/* return 1 if point in tetra, adjacent #, if not */int inSubTetra(pPoint pt[4],float *p,double *cb) {  double   bx,by,bz,cx,cy,cz,dx,dy,dz,vx,vy,vz,apx,apy,apz;  double   epsra,vol1,vol2,vol3,vol4,dd;   /* barycentric */  bx  = pt[1]->c[0] - pt[0]->c[0];  by  = pt[1]->c[1] - pt[0]->c[1];  bz  = pt[1]->c[2] - pt[0]->c[2];  cx  = pt[2]->c[0] - pt[0]->c[0];  cy  = pt[2]->c[1] - pt[0]->c[1];  cz  = pt[2]->c[2] - pt[0]->c[2];  dx  = pt[3]->c[0] - pt[0]->c[0];  dy  = pt[3]->c[1] - pt[0]->c[1];  dz  = pt[3]->c[2] - pt[0]->c[2];  /* test volume */  vx  = cy*dz - cz*dy;  vy  = cz*dx - cx*dz;  vz  = cx*dy - cy*dx;  epsra = EPST*(bx*vx + by*vy + bz*vz);  apx = p[0] - pt[0]->c[0];  apy = p[1] - pt[0]->c[1];  apz = p[2] - pt[0]->c[2];  /* p in 2 */  vol2 = apx*vx + apy*vy + apz*vz;  if ( epsra > vol2 )  return(-1);  /* p in 3 */  vx  = by*apz - bz*apy;  vy  = bz*apx - bx*apz;  vz  = bx*apy - by*apx;  vol3 = dx*vx + dy*vy + dz*vz;  if ( epsra > vol3 )  return(-2);    /* p in 4 */  vol4 = -cx*vx - cy*vy - cz*vz;  if ( epsra > vol4 )  return(-3);  /* p in 1 */  vol1 = -epsra * EPSR - vol2 - vol3 - vol4;  if ( epsra > vol1 )  return(0);  dd = vol1+vol2+vol3+vol4;  if ( dd != 0.0f )  dd = 1.0 / dd;  cb[0] = vol1 * dd;  cb[1] = vol2 * dd;  cb[2] = vol3 * dd;  cb[3] = vol4 * dd;     return(1);}int locateHexa(pMesh mesh,int nsdep,int base,float *p,double *cb,pPoint pt[4]) {  pHexa    ph;  double   bx,by,bz,cx,cy,cz,dx,dy,dz,vx,vy,vz,apx,apy,apz;  double   epsra,vol1,vol2,vol3,vol4,dd;   int     *adj,iadr,it,nsfin,in;  it    = 0;  nsfin = nsdep;  /*printf("locateHexa: searching for %f %f %f\n",p[0],p[1],p[2]);*/  do {    if ( !nsfin )  return(0);    ph = &mesh->hexa[nsfin];/*printf("\nnsfin %d  base %d  mark %d\n",nsfin,base,ph->mark);*/    if ( !ph->v[0] || ph->mark == base )  return(0);    ph->mark = base;    iadr = 6*(nsfin-1)+1;    adj  = &mesh->adja[iadr];/*printf("adj %d %d %d %d %d %d\n",adj[0],adj[1],adj[2],adj[3],adj[4],adj[5]);*/    /* tetra1: 0,2,3,7 : 3 external faces *//*printf("tet1: %d %d %d %d\n",ph->v[0],ph->v[2],ph->v[3],ph->v[7]);*/    pt[0] = &mesh->point[ph->v[0]];    pt[1] = &mesh->point[ph->v[2]];    pt[2] = &mesh->point[ph->v[3]];    pt[3] = &mesh->point[ph->v[7]];    in = inSubTetra(pt,p,cb);printf("tet1 : on sort en %d\n",in);    if ( in > 0 ) {      ph->cpt++;      return(nsfin);    }    else if ( in == 0 ) {      nsfin = adj[4];      continue;    }    else if ( in == -1 ) {      nsfin = adj[5];      continue;    }    else if ( in == -3 ) {      nsfin = adj[0];      continue;    }    /* tetra2: 1,4,5,6 : 3 external faces */    pt[0] = &mesh->point[ph->v[1]];    pt[1] = &mesh->point[ph->v[4]];    pt[2] = &mesh->point[ph->v[5]];    pt[3] = &mesh->point[ph->v[6]];    in = inSubTetra(pt,p,cb);    if ( in > 0 ) {      ph->cpt++;      return(nsfin);    }    else if ( in == 0 ) {      nsfin = adj[1];      continue;    }    else if ( in == -1 ) {      nsfin = adj[3];      continue;    }    else if ( in == -3 ) {      nsfin = adj[2];      continue;    }    /* tetra3: 0,4,6,7 : 2 external faces */    pt[0] = &mesh->point[ph->v[0]];    pt[1] = &mesh->point[ph->v[4]];    pt[2] = &mesh->point[ph->v[6]];    pt[3] = &mesh->point[ph->v[7]];    in = inSubTetra(pt,p,cb);    if ( in > 0 ) {      ph->cpt++;      return(nsfin);    }    else if ( in == 0 ) {      nsfin = adj[1];      continue;    }    else if ( in == -2 ) {      nsfin = adj[5];      continue;    }    /* tetra4: 0,1,2,6 : 2 external faces */    pt[0] = &mesh->point[ph->v[0]];    pt[1] = &mesh->point[ph->v[1]];    pt[2] = &mesh->point[ph->v[2]];    pt[3] = &mesh->point[ph->v[6]];    in = inSubTetra(pt,p,cb);    if ( in > 0 ) {      ph->cpt++;      return(nsfin);    }    else if ( in == 0 ) {      nsfin = adj[3];      continue;    }    else if ( in == -3 ) {      nsfin = adj[0];      continue;    }        /* tetra5: 0,6,2,7 : 1 external face */    pt[0] = &mesh->point[ph->v[0]];    pt[1] = &mesh->point[ph->v[6]];    pt[2] = &mesh->point[ph->v[2]];    pt[3] = &mesh->point[ph->v[7]];    in = inSubTetra(pt,p,cb);    if ( in > 0 ) {      ph->cpt++;      return(nsfin);    }    else if ( in == 0 ) {      nsfin = adj[4];      continue;    }    /* tetra6: 0,4,1,6 : 1 external face */    pt[0] = &mesh->point[ph->v[0]];    pt[1] = &mesh->point[ph->v[4]];    pt[2] = &mesh->point[ph->v[1]];    pt[3] = &mesh->point[ph->v[6]];    in = inSubTetra(pt,p,cb);    if ( in > 0 ) {      ph->cpt++;      return(nsfin);    }    else if ( in == -3 ) {      nsfin = adj[2];      continue;    }puts("PROBLEME");exit(1);  }  while ( ++it <= mesh->nhex );  return(0);}int locateTria(pMesh mesh,int nsdep,int base,float *p,double *cb) {  pTriangle pt;  pPoint    p0,p1,p2;  double    ax,ay,bx,by,cx,cy;  double    epsra,aire1,aire2,aire3,dd;   int      *adj,iadr,it,isign,nsfin;  it    = 0;  nsfin = nsdep;  /*printf("locateTria: searching for %f %f\n",p[0],p[1]);*/  do {    pt = &mesh->tria[nsfin];    if ( !pt->v[0] )  return(0);    if ( pt->mark == base )  return(0);    pt->mark = base;    iadr = 3*(nsfin-1)+1;    adj  = &mesh->adja[iadr];    p0 = &mesh->point[pt->v[0]];    p1 = &mesh->point[pt->v[1]];    p2 = &mesh->point[pt->v[2]];    ax = p1->c[0] - p0->c[0];    ay = p1->c[1] - p0->c[1];    bx = p2->c[0] - p0->c[0];    by = p2->c[1] - p0->c[1];    dd = ax*by - ay*bx;    isign= dd > 0 ? 1 : -1;    epsra = isign > 0 ? EPST*dd : -(EPST*dd);    /* barycentric */    bx = p1->c[0] - p[0];    by = p1->c[1] - p[1];    cx = p2->c[0] - p[0];    cy = p2->c[1] - p[1];    /* p in 1 */    aire1 = isign*(bx*cy - by*cx);    if ( epsra > aire1 ) {      nsfin = adj[0];      continue;    }    ax = p0->c[0] - p[0];    ay = p0->c[1] - p[1];    aire2 = isign*(cx*ay - cy*ax);    if ( epsra > aire2 ) {      nsfin = adj[1];      continue;    }    aire3 = -epsra*EPSR - aire1 - aire2;    if ( epsra > aire3 ) {      nsfin = adj[2];      continue;    }    dd = aire1+aire2+aire3;    if ( dd != 0.0f )  dd = 1.0 / dd;    cb[0] = aire1 * dd;    cb[1] = aire2 * dd;    cb[2] = aire3 * dd;        pt->cpt++;    return(nsfin);  }  while ( ++it <= mesh->nt );  return(0);}/* point in tetra */int inTetra(pMesh mesh,int nsdep,float *p,double *cb) {  pTetra   pt;  pPoint   p0,p1,p2,p3;  double   bx,by,bz,cx,cy,cz,dx,dy,dz,vx,vy,vz,apx,apy,apz;  double   epsra,vol1,vol2,vol3,vol4,dd;   pt = &mesh->tetra[nsdep];  if ( !pt->v[0] )  return(0);  p0 = &mesh->point[pt->v[0]];  p1 = &mesh->point[pt->v[1]];  p2 = &mesh->point[pt->v[2]];  p3 = &mesh->point[pt->v[3]];  /* barycentric */  bx  = p1->c[0] - p0->c[0];  by  = p1->c[1] - p0->c[1];  bz  = p1->c[2] - p0->c[2];  cx  = p2->c[0] - p0->c[0];  cy  = p2->c[1] - p0->c[1];  cz  = p2->c[2] - p0->c[2];  dx  = p3->c[0] - p0->c[0];  dy  = p3->c[1] - p0->c[1];  dz  = p3->c[2] - p0->c[2];  /* test volume */  vx  = cy*dz - cz*dy;  vy  = cz*dx - cx*dz;  vz  = cx*dy - cy*dx;  epsra = EPST*(bx*vx + by*vy + bz*vz);  apx = p[0] - p0->c[0];  apy = p[1] - p0->c[1];  apz = p[2] - p0->c[2];  /* p in 2 */  vol2  = apx*vx + apy*vy + apz*vz;  if ( epsra > vol2 )  return(0);  /* p in 3 */  vx  = by*apz - bz*apy;  vy  = bz*apx - bx*apz;  vz  = bx*apy - by*apx;  vol3 = dx*vx + dy*vy + dz*vz;  if ( epsra > vol3 )  return(0);      /* p in 4 */  vol4 = -cx*vx - cy*vy - cz*vz;  if ( epsra > vol4 )  return(0);    /* p in 1 */  vol1 = -epsra * EPSR - vol2 - vol3 - vol4;  if ( epsra > vol1 )  return(0);  dd = vol1+vol2+vol3+vol4;  if ( dd != 0.0f )  dd = 1.0 / dd;  cb[0] = vol1 * dd;  cb[1] = vol2 * dd;  cb[2] = vol3 * dd;  cb[3] = vol4 * dd;   pt->cpt++;  return(1);}int inHexa(pMesh mesh,int nsdep,float *p,double *cb,pPoint pt[4]) {  return(0);}int inTria(pMesh mesh,int nsdep,float *p,double *cb) {  pTriangle  pt;  pPoint     p0,p1,p2;  double     ax,ay,bx,by,cx,cy;  double     epsra,dd,aire1,aire2,aire3;  int        isign;  pt = &mesh->tria[nsdep];  if ( !pt->v[0] )  return(0);  p0 = &mesh->point[pt->v[0]];  p1 = &mesh->point[pt->v[1]];  p2 = &mesh->point[pt->v[2]];  ax = p1->c[0] - p0->c[0];  ay = p1->c[1] - p0->c[1];  bx = p2->c[0] - p0->c[0];  by = p2->c[1] - p0->c[1];  dd = ax*by - ay*bx;  isign= dd > 0 ? 1 : -1;  epsra = isign > 0 ? EPST*dd : -(EPST*dd);  /* barycentric */  bx = p[0] - p1->c[0];  by = p[1] - p1->c[1];  cx = p[0] - p2->c[0];  cy = p[1] - p2->c[1];  aire1 = isign*(bx*cy - by*cx);  if ( epsra > aire1 )  return(0);  ax = p[0] - p0->c[0];  ay = p[1] - p0->c[1];  aire2 = isign*(cx*ay - cy*ax);  if ( epsra > aire2 )  return(0);    aire3 = -epsra*EPSR - aire1 - aire2;  if ( epsra > aire3 )  return(0);  dd = aire1+aire2+aire3;  if ( dd != 0.0f )  dd = 1.0 / dd;  cb[0] = aire1 * dd;  cb[1] = aire2 * dd;

⌨️ 快捷键说明

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