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

📄 cogengrid.cxx

📁 有限元学习研究用源代码(老外的),供科研人员参考
💻 CXX
字号:
#include "cogengrid.hxx"

#include "wzwarning.hxx"
static wzCounter cogInfoPointCalls(wzCounter::report_severity,
			      "CogenGrid::Point called","CogenGrid::Point calls: <>\n");
static wzCounter cogInfoPointCallCells(wzCounter::report_severity,
			      "CogenGrid::Point cell tested","CogenGrid::Point cells tested: <>\n");
static wzCounter cogInfoLineCalls(wzCounter::report_severity,
			      "CogenGrid::line called","CogenGrid::line calls: <>\n");
static wzCounter cogInfoFaceNotFound(wzCounter::report_severity,
			      "CogenGrid::face not found","CogenGrid::faces not found: <>\n");
static wzCounter cogInfoReverse(wzCounter::report_severity,
			      "CogenGrid::reverse used","CogenGrid::reverse used: <>\n");
static wzCounter cogInfoReverse2(wzCounter::report_severity,
			      "CogenGrid::reverse 2 used","CogenGrid::reverse 2 used: <>\n");

const wzIndex wzCellOfPoint=0;
static int sig[2] = {1,-1};

cogenGrid CogenGrid::cogengrid()
{return this;}

void CogenGrid::setDelta(cogFloat delta)
{
  Cogeometry::setDelta(delta);
  epsilon1 = delta;
  epsilon2 = epsilon1*epsilon1/2.0;
  epsilon3 = epsilon1*epsilon2/3.0;
}

wzIndex CogenGrid::Point(wzPoint& p0) const
{
  int *cn0;
  int c0,c1,ch,cv0,nl,i,i0,sl,co;
  wzCellType t,th;
  wzFloat *x= p0.X;
  double vv[4],xx,yy,zz,x1,x2,x3,y1,y2,y3,z1,z2,z3;
  wzFloat* ff[IBG2CNMAX];
  register wzFloat *fj;
  cogInfoPointCalls++;
  xx = x[0]; yy = x[1]; zz = x[2];
#define cvmax 3
  cv0=0;
  if(Startpoint == 0){
    if(lastCellUsed == 0){
      wzRangeLoop(grid->cells,c0){
	if(grid->ccdef(c0)) break;
      }
    }else{
      c0 = lastCellUsed;
    }
  }else{
    c0=Startpoint->I[wzCellOfPoint]; setStartpoint(0);
  }
  switch(wzCellTypeCODIM(t=grid->cct(c0))){
    /*
      case wzIsNode:
      co=wzGridCOutFirst(*gg,c0,t);
      c0=wzGridCOutside(*gg,co);
      t =cct(c0);       
      case wzIsEdge:
      co=wzGridCOutFirst(*gg,c0,t);
      c0=wzGridCOutside(*gg,co);
      t =cct(c0);
      */
  case wzIsFace:
    co=grid->ccleft(c0,t);
    if(grid->ccdef(co))	c0=co;
    else		c0=grid->ccright(c0,t);
    t = grid->cct(c0);
  }
gridRegionBegin:
  cogInfoPointCallCells++;
  wzAssert(grid->ccdef(c0));
  nl=wzCellTypePoints(t=grid->cct(c0)); cn0=grid->ccn(c0);
  for(i=0;i<nl;i++) ff[i]=grid->cnx(cn0[i]);
  sl=wzCellTypeSides(t);
  wzAssert(wzCellTypeCODIM(t)==wzIsRegion);
  i0 = 0;
gridRegionContinue:
  switch(wzCellTypeGDIM(t)){
  case 1:
    for(i=i0;i<sl;i++){
      if((vv[i]=sig[i]*(xx-ff[i][0]))<0) {goto gridRegionNext;}
    } break;
  case 2:
    for(i=i0;i<sl;i++){
      fj = ff[wzCellTypeEPoint1(t,i)];
      x1 = fj[0] - xx; y1 = fj[1] - yy;
      fj = ff[wzCellTypeEPoint2(t,i)];
      x2 = fj[0] - xx; y2 = fj[1] - yy;
      vv[i] = x1 * y2 - x2 * y1;
      if((vv[i]<-epsilon2)||((vv[i]<0)&&(cv0++<cvmax))) goto gridRegionNext;
    } break;
  case 3:
    for(i=i0;i<sl;i++){
      fj = ff[wzCellTypeSPoint1(t,i,0)];
      x1 = fj[0] - xx; y1 = fj[1] - yy; z1 = fj[2] - zz;
      fj = ff[wzCellTypeSPoint1(t,i,1)];
      x2 = fj[0] - xx; y2 = fj[1] - yy; z2 = fj[2] - zz;
      fj = ff[wzCellTypeSPoint1(t,i,2)];
      x3 = fj[0] - xx; y3 = fj[1] - yy; z3 = fj[2] - zz;
      vv[i] = -(x1*(y2*z3-y3*z2) + x2*(y3*z1-y1*z3) + x3*(y1*z2-y2*z1));
      if((vv[i]<-epsilon3)||((vv[i]<0)&&(cv0++<cvmax))) goto gridRegionNext;
    } break;
  }
  goto gridRegionEnd;
gridRegionNext:
  c1=grid->ccs(c0)[i];
  if(grid->ccund(c1)){
    i0 = i+1; goto gridRegionContinue;
  }else if(wzCellTypeCODIM(th=grid->cct(c1))==wzIsFace){
    if(c0==(ch=grid->ccright(c1,th)))	c1=grid->ccleft(c1,th);
    else					c1=ch;
    if(grid->ccund(c1)){
      i0 = i+1; goto gridRegionContinue;
    }
  }
  c0=c1;
  goto gridRegionBegin;
gridRegionEnd:
#ifdef wzFloatValues
  vvs=0;
  for(i=0;i<sl;i++) vvs	  += vv[i];
  for(i=0;i<sl;i++) vv[i] /= vvs;
  cn0=grid->ccn(c0);
  for(f=0;f<functions;f++){
    fv=0;
    for(i=0;i<sl;i++) fv += vv[i]*(grid->cnf(cn0[i]))[fn];
    p0.F[fn] = fv;
  }
#endif
  p0.S = (wzRegion) grid->ccu(c0);
  p0.I[wzCellOfPoint] = c0;
  ((CogenGrid*)this)->lastCellUsed = c0;
  return cogRCRegionFound;
}

static int suppress_unreachable_warning = 1;
wzIndex	CogenGrid::Line (cogFlag1& f, const cogLine& s) const
{
  int c0,c1,ch,c2,cb,cr,nl,i,ii,io,in,sl,*cn0,*cs0,mark[IBG2CSMAX];
  wzCellType t,th;
  wzRegion u,ur;
  wzFace ub;
  double vv0,vv1,vv2,vv3,vvv,p1,p2;
  double xb,xe,xbo,xeo,x1,xx0,xx1,xx2,xx3;
  double yb,ye,ybo,yeo,y1,yy0,yy1,yy2,yy3;
  double zb,ze,zbo,zeo,z1,zz0,zz1,zz2,zz3;
  wzFloat*	ff[IBG2CNMAX];
  register wzFloat *fj,dd;
  if(suppress_unreachable_warning) return Cogeometry::Line(f,s);
  cogInfoLineCalls++;
  int reverse=0;  // is 1 only if no boundary has been found starting from s.c0
  c0 = s.c0.I[wzCellOfPoint]; 
  c2 = s.c1.I[wzCellOfPoint];
  xbo = xb = s.c0[0];
  ybo = yb = s.c0[1];
  zbo = zb = s.c0[2];
  xeo = xe = s.c1[0];
  yeo = ye = s.c1[1];
  zeo = ze = s.c1[2];
  xx0 = xb-xe; yy0 = yb-ye; zz0 = zb-ze;
  u = grid->ccu(c0);
begin:
  wzAssert(grid->ccdef(c0));
  t=grid->cct(c0);  
  nl=wzCellTypePoints(t); cn0=grid->ccn(c0);
  sl=wzCellTypeSides (t); cs0=grid->ccs(c0);
  wzAssert(wzCellTypeCODIM(t)==wzIsRegion);
  for(i=0;i<nl;i++) ff[i]=grid->cnx(cn0[i]);
  // initializing the mark field: impossible neighbours marked.
  for(i=0;i<sl;i++){	
    if((ch=cs0[i])>0){
      switch(wzCellTypeCODIM(th=grid->cct(ch))){
      case wzIsFace:
	if((c1=grid->ccleft(ch,th))<=0){
	  {mark[i]=1;break;}
	}else if(c1==c0){
	  if((c1=grid->ccright(ch,th))<=0)
	    {mark[i]=1;break;}
	}
	if(grid->ccu(c1)<=0)
	  {mark[i]=1;break;}
      case wzIsRegion:
      default:
	mark[i]=0; break;
      }
    }else{
      // ???     mark[i]=0;
      mark[i]=1;
    }
  }
  //  now we want to find the optimal neighbour side ii and go to
  //  side_found. It should not be a marked side, the end node should be
  //  on the correct side, and if there remains some choice after this
  //  it is the side which intersects the line (xb,xe):
  switch(wzCellTypeGDIM(t)){
  case 1:
    if((vv0=(xe - ff[0][0]))<0) {ii=0; goto side_found;}
    if((vv0=(ff[1][0] - xe))<0) {ii=1; goto side_found;}
    goto end_is_inside;
  case 2:
    for(i=0;i<sl;i++){
      ii=i; io= -1;
    begin_2:
      fj  = ff[wzCellTypeSPoint1(t,ii,0)];
      xx1 = fj[0] - xe; yy1 = fj[1] - ye;
      fj  = ff[wzCellTypeSPoint1(t,ii,1)];
      xx2 = fj[0] - xe; yy2 = fj[1] - ye;
      vv0 = xx1*yy2 - xx2*yy1;
      if(vv0>=0) {
	mark[ii]=1; 
	if(io>-1) {ii=io; io= -1; goto begin_2;}
	else continue;
      }
      vv1 = xx0*yy2 - xx2*yy0;
      if(vv1>0) {
	in=wzCellTypeSSide(t,ii,1);
	if(mark[in]==0) {mark[ii]=2; io=ii; ii=in; goto begin_2;}
      }
      vv2 = xx1*yy0 - xx0*yy1;
      if(vv2>0) {
	in=wzCellTypeSSide(t,ii,0);
	if(mark[in]==0) {mark[ii]=2; io=ii; ii=in; goto begin_2;}
      }
      goto side_found;
    } 
    goto end_is_inside;
  case 3:
    for(i=0;i<sl;i++){
      ii=i; io= -1;
    begin_3:
      fj  = ff[wzCellTypeSPoint1(t,ii,0)];
      xx1 = fj[0] - xe; yy1 = fj[1] - ye; zz1 = fj[2] - ze;
      fj  = ff[wzCellTypeSPoint1(t,ii,1)];
      xx2 = fj[0] - xe; yy2 = fj[1] - ye; zz2 = fj[2] - ze;
      fj  = ff[wzCellTypeSPoint1(t,ii,2)];
      xx3 = fj[0] - xe; yy3 = fj[1] - ye; zz3 = fj[2] - ze;
      vv0 = xx1*(yy2*zz3-yy3*zz2)
	+   xx2*(yy3*zz1-yy1*zz3)
	+   xx3*(yy1*zz2-yy2*zz1);
      if(vv0<=0) {
	mark[ii]=1; 
	if(io>-1) {ii=io; io= -1; goto begin_3;}
	else continue;
      }
      vv1 = xx0*(yy2*zz3-yy3*zz2)
	+   xx2*(yy3*zz0-yy0*zz3)
	+   xx3*(yy0*zz2-yy2*zz0);
      if(vv1<0) {
	in=wzCellTypeSSide(t,ii,1);
	if(mark[in]==0) {mark[ii]=2; io=ii; ii=in; goto begin_3;}
      }
      vv2 = xx1*(yy0*zz3-yy3*zz0)
	+   xx0*(yy3*zz1-yy1*zz3)
	+   xx3*(yy1*zz0-yy0*zz1);
      if(vv2<0) {
	in=wzCellTypeSSide(t,ii,2);
	if(mark[in]==0) {mark[ii]=2; io=ii; ii=in; goto begin_3;}
      }
      vv3 = xx1*(yy2*zz0-yy0*zz2)
	+   xx2*(yy0*zz1-yy1*zz0)
	+   xx0*(yy1*zz2-yy2*zz1);
      if(vv3<0) {
	in=wzCellTypeSSide(t,ii,0);
	if(mark[in]==0) {mark[ii]=2; io=ii; ii=in; goto begin_3;}
      }
      goto side_found;
    } 
    goto end_is_inside;

  }
side_found:
  cb=grid->ccs(c0)[ii]; t=grid->cct(cb);
  if(wzCellTypeCODIM(t)==wzIsFace) {
    if(reverse){
      if(c0==(cr=grid->ccleft(cb,t))) cr=grid->ccright(cb,t);
      else wzAssert(c0==grid->ccright(cb,t));
      if(grid->ccu(cr)!=grid->ccu(c2)) {wzAssert(0); c0=cr; goto begin;}
    }
    goto intersection_found;
  }
  wzAssert(wzCellTypeCODIM(t)==wzIsRegion);
  if(cb==c2) {
    cogInfoFaceNotFound++;
    return cogRCFaceNotFound;
  }
  if(u!=grid->ccu(cr)){
    cr = cb; cb = 0; wzAssert(0); goto intersection_found;
  }
  c0=cb; goto begin;
end_is_inside:
  // xe is inside of c0 or behind an outer boundary of c0.
  // That's ok if the regions of c0 and c2 are identical:
  if(grid->ccu(c0)==grid->ccu(c2)){
    cogInfoFaceNotFound++;
    return cogRCFaceNotFound;
  }
  // We have not found any intersection, but the ends are in different regions.
  // Let's try the other direction.
  if(!reverse){
    cogInfoReverse++;
    reverse = 1;
    c0 = s.c1.I[wzCellOfPoint];
    c2 = s.c0.I[wzCellOfPoint];
    xbo = xb = s.c1[0];
    ybo = yb = s.c1[1];
    zbo = zb = s.c1[2];
    xeo = xe = s.c0[0];
    yeo = ye = s.c0[1];
    zeo = ze = s.c0[2];
    xx0 = xb-xe; yy0 = yb-ye; zz0 = zb-ze;
    u = grid->ccu(c0);
    goto begin;
  }
  // Seems, the whole line is on the boundary.  We choose the starting
  // point as the boundary point, but create an artificial boundary.
  // wzAssert(0);	// not yet implemented
  cogInfoReverse2++;
  ub = 1; 
  u  = grid->ccu(c2);
  ur = grid->ccu(c0);
  vv0= s.diameter(); vvv = -Delta;
  goto return_intersection;
intersection_found:
  ub = grid->ccu(cb);
  ur = grid->ccu(cr);
  switch(wzCellTypeGDIM(t)){
  case 1:
    if(ii)	vvv = xb - ff[0][0];
    else	vvv = ff[1][0] - xb;
    if(vvv<0) vvv=0;
    break;
  case 2:
    vvv	= (xx1-xx0)*(yy2-yy0) - (xx2-xx0)*(yy1-yy0);
    if(vvv<0) vvv=0;
    break;
  case 3:
    yy1 -= yy0; yy2 -= yy0; yy3 -= yy0;
    zz1 -= zz0; zz2 -= zz0; zz3 -= zz0;
    vvv	= (xx1-xx0)*(yy2*zz3-yy3*zz2)
      +   (xx2-xx0)*(yy3*zz1-yy1*zz3)
      +   (xx3-xx0)*(yy1*zz2-yy2*zz1);
    if(vvv>0) vvv=0;
    break;
  }
return_intersection:
  p1=vv0/(vv0-vvv); p2=vvv/(vvv-vv0); // correct if reverse???
  f.p1[0] = x1 = p1*xbo + p2*xeo;
  f.p1[1] = y1 = p1*ybo + p2*yeo;
  f.p1[2] = z1 = p1*zbo + p2*zeo;
  f.p1.I[wzCellOfPoint]	= c0;
  dd = 0.5*Delta/s.diameter();
  f.p0[0] = x1 + dd*(xbo-xeo);
  f.p0[1] = y1 + dd*(ybo-yeo);
  f.p0[2] = z1 + dd*(zbo-zeo);
  f.po[0] = x1 - dd*(xbo-xeo);
  f.po[1] = y1 - dd*(ybo-yeo);
  f.po[2] = z1 - dd*(zbo-zeo);
  f.p1.S = wzFace(ub);
  f.p0.S = wzFace(u);
  f.po.S = wzFace(ur);
#ifdef wzFloatValues
 cn0=ccn(cb); sl=wzCellTypePoints(t);
 switch(wzCellTypeGDIM(t)){
  case 1: vv[0]=1.0;
	break;
  case 2: x = p1*xb + p2*xe; y = p1*yb + p2*ye;
	f0=gnx(gg,cn0[0]); f1=gnx(gg,cn0[1]);
	xx0=f1[0]-f0[0]; yy0=f1[1]-f0[1];
	vv[0]=(f1[0]-x)*xx0 + (f1[1]-y)*yy0;
	vv[1]=(x-f0[0])*xx0 + (y-f0[1])*yy0;
	vvs  = vv[0]+vv[1];
	vv[0] /= vvs; vv[1] /= vvs;
	break;
  case 3:  x = p1*xb + p2*xe; y = p1*yb + p2*ye; z = p1*zb + p2*ze;
	f0=gnx(gg,cn0[0]); f1=gnx(gg,cn0[1]); f2=gnx(gg,cn0[2]);
	xx0=(f1[1]-f0[1])*(f2[2]-f0[2]) - (f1[2]-f0[2])*(f2[1]-f0[1]);
	yy0=(f1[2]-f0[2])*(f2[0]-f0[0]) - (f1[0]-f0[0])*(f2[2]-f0[2]);
	zz0=(f1[0]-f0[0])*(f2[1]-f0[1]) - (f1[1]-f0[1])*(f2[0]-f0[0]);
	vv[0] = (f1[0]-x)*(yy0*(f2[2]-z) - zz0*(f2[1]-y))
	      + (f1[1]-y)*(zz0*(f2[0]-x) - xx0*(f2[2]-z))	
	      + (f1[2]-z)*(xx0*(f2[1]-y) - yy0*(f2[0]-x));	
	vv[1] = (f2[0]-x)*(yy0*(f0[2]-z) - zz0*(f0[1]-y))
	      + (f2[1]-y)*(zz0*(f0[0]-x) - xx0*(f0[2]-z))	
	      + (f2[2]-z)*(xx0*(f0[1]-y) - yy0*(f0[0]-x));	
	vv[2] = (f0[0]-x)*(yy0*(f1[2]-z) - zz0*(f1[1]-y))
	      + (f0[1]-y)*(zz0*(f1[0]-x) - xx0*(f1[2]-z))	
	      + (f0[2]-z)*(xx0*(f1[1]-y) - yy0*(f1[0]-x));	
	vvs   = vv[0]+vv[1]+vv[2];
	vv[0] /= vvs; vv[1] /= vvs; vv[2] /= vvs;
	break;
 }
 for(f=0;f<grdf->fanz;f++){
	fn=grdf->flist[f];
	fv=0;
	for(i=0;i<sl;i++) fv += vv[i]*(ibg2pF(ccn(cn0[i]))[fn]);
	ibg2pF(*nint)[fn]=fv;
 }
#endif
 return cogRCFaceFound;
}

⌨️ 快捷键说明

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