cogenoctree.cxx

来自「有限元学习研究用源代码(老外的),供科研人员参考」· CXX 代码 · 共 309 行

CXX
309
字号
#include "ibgoctree.hxx"
#include "ibg2.hxx"
#include <stdlib.h>
#include "cogenoctree.hxx"
#include "ibggenerator.hxx"
#include "cogwarnings.hxx"

wzFloat  CogenOctree::epsilon = 1.e-7;

cogenOctree	CogenOctree::cogenoctree() const {return (CogenOctree *) this;}

CogenOctree::CogenOctree()
  :blist(sizeof(CogenOctreeBox))
  ,flist(sizeof(CogenOctreeFace))
  ,rlist(sizeof(CogenOctreeRefineItem))
  ,box(blist.base)
  ,face(flist.base)
  ,refine(rlist.base)
  ,boundaryLevel(4)
{
  setBox();
}

void CogenOctree::setBorder(
			    wzFloat xmin, wzFloat xmax,
			    wzFloat ymin, wzFloat ymax,
			    wzFloat zmin, wzFloat zmax)
{
  min[0]=xmin;  max[0]=xmax;
  min[1]=ymin;  max[1]=ymax;
  min[2]=zmin;  max[2]=zmax;
  for(int i=0;i<wzPointDim;i++){
    if(min[i] != -wzInfty) addPlane(i,min[i]);
    if(max[i] !=  wzInfty) addPlane(i,max[i]);
  }
}

void CogenOctree::addPlane(wzIndex dir, wzFloat x)
{
  if(x>=min[dir] && x<=max[dir]) wzTensorGrid::add(dir,x);
}

void CogenOctree::setFaceInBox(wzFace f,
			      wzFloat xmin,wzFloat xmax,
			      wzFloat ymin,wzFloat ymax,
			      wzFloat zmin,wzFloat zmax)
{
  wzFloat Min[3]={xmin,ymin,zmin};
  wzFloat Max[3]={xmax,ymax,zmax};
  setFaceInBox(f,Min,Max);
}

void CogenOctree::setFaceInBox(wzFace f, wzFloat *xmin, wzFloat *xmax)
{
  int i;
  for(i=0;i<3;i++){
    if(xmax[i]<min[i]){cogInfoEmptyFace();}
    if(xmin[i]>max[i]){cogInfoEmptyFace();}
  }
  wzIndex l = flist.create();
  face[l].face = f;
  for(i=0;i<3;i++){
    if(xmin[i]<min[i])	face[l].min[i] = min[i];
    else		face[l].min[i] = xmin[i];
    if(xmax[i]>max[i])	face[l].max[i] = max[i];
    else		face[l].max[i] = xmax[i];
  }
}

wzIndex CogenOctree::addBox(wzRegion r,
			    wzFloat xmin,wzFloat xmax,
			    wzFloat ymin,wzFloat ymax,
			    wzFloat zmin,wzFloat zmax)
{
  wzFloat Min[3]={xmin,ymin,zmin};
  wzFloat Max[3]={xmax,ymax,zmax};
  return addBox(r,Min,Max);
}

wzIndex CogenOctree::addBox(wzRegion r,wzFloat *xmin, wzFloat *xmax)
{
  int i;
  for(i=0;i<3;i++){
    if(xmax[i]<min[i]){cogInfoEmptyRegion();}
    if(xmin[i]>max[i]){cogInfoEmptyRegion();}
  }
  wzIndex l = blist.create();
  box[l].region = r;
  for(i=0;i<3;i++){
    if(xmin[i]<min[i])	box[l].min[i] = min[i];
    else		box[l].min[i] = xmin[i];
    if(xmax[i]>max[i])	box[l].max[i] = max[i];
    else		box[l].max[i] = xmax[i];
  }
  return l;
}

static const wzFloat dfac = 1+1.e-7;
static const wzFloat dadd = 1/(wzInfty*wzInfty);

wzIndex CogenOctree::refinementInBox(wzFloat dx, wzFloat dy, wzFloat dz, wzIndex b)
{
  wzIndex r = rlist.create(); wzFloat dd;
  refine[r].box = b;
  dd = dfac*dx*dx + dadd;  refine[r].dist[0] = 1/dd;
  dd = dfac*dy*dy + dadd;  refine[r].dist[1] = 1/dd;
  dd = dfac*dz*dz + dadd;  refine[r].dist[2] = 1/dd;
  return r;
}

void CogenOctree::setFaceOfBox(wzFace f, wzIndex r)
{
  CogenOctreeBox& reg = *(box+r);
  setFaceInBox(f,reg.min,reg.max);
}

void CogenOctree::setFaceOfBoxSide(wzFace f, wzIndex r, wzIndex dir)
{
  CogenOctreeBox& R = *(box+r);
  switch(dir){
  case 0: setFaceInBox(f,R.max[0],R.max[0],R.min[1],R.max[1],R.min[2],R.max[2]); break;
  case 1: setFaceInBox(f,R.min[0],R.max[0],R.max[1],R.max[1],R.min[2],R.max[2]); break;
  case 2: setFaceInBox(f,R.min[0],R.max[0],R.min[1],R.max[1],R.max[2],R.max[2]); break;
  case 3: setFaceInBox(f,R.min[0],R.min[0],R.min[1],R.max[1],R.min[2],R.max[2]); break;
  case 4: setFaceInBox(f,R.min[0],R.max[0],R.min[1],R.min[1],R.min[2],R.max[2]); break;
  case 5: setFaceInBox(f,R.min[0],R.max[0],R.min[1],R.max[1],R.min[2],R.min[2]); break;
  }
}

void CogenOctree::endInitialization()
{
  int i,l;
  wzFloat delta;
  if(checked) return;
  wzFloat eps = epsilon;
  wzRangeLoop(blist,l){
    CogenOctreeBox& rr = box[l];
    addPlanesOfPoint(rr.min[0],rr.min[1],rr.min[2]);
    addPlanesOfPoint(rr.max[0],rr.max[1],rr.max[2]);
    for(i=0;i<3;i++){
      if(rr.min[i]>=0)
	rr.min[i] -= eps*(rr.max[i]-rr.min[i]);
      else
	rr.min[i] += eps*rr.min[i];
      if(rr.max[i]>=0)
	rr.max[i] += eps*(rr.max[i]-rr.min[i]);
      else
	rr.max[i] -= eps*rr.max[i];
    }
  }
  wzRangeLoop(flist,l){
    CogenOctreeFace& ff = face[l];
    addPlanesOfPoint(ff.min[0],ff.min[1],ff.min[2]);
    addPlanesOfPoint(ff.max[0],ff.max[1],ff.max[2]);
  }
  wzTensorGrid::endInitialization(min,max);
  wzTensorGrid::getBox(min,max);
  if(max[0]>min[0]) delta = max[0]-min[0];
  if(max[1]>min[1] && max[1]<min[1]+delta) delta = max[1]-min[1];
  if(max[2]>min[2] && max[2]<min[2]+delta) delta = max[2]-min[2];
  setDelta(Delta*delta);
  wzRangeLoop(flist,l){
    CogenOctreeFace& ff = face[l];
    for(i=0;i<3;i++){
      ff.min[i] -= Delta; 
      ff.max[i] += Delta;
    }
  }
}

wzBoolean CogenOctree::inBox(wzIndex b, const wzPoint& p) const
{
  CogenOctreeBox& d = *(box+b);
  int i;
  wzFloat Y[wzPointDim];
  try{
    y(Y,p);
    for(i=0;i<wzPointDim;i++){
      if(d.min[i]>Y[i]) return wzFalse;
      if(d.max[i]<Y[i]) return wzFalse;
    }
  }catch(...){return wzFalse;}
  return wzTrue;
}

void CogenOctree::getMetric(wzMetricData& data, const wzPoint& p) const
{
  wzIndex it,i,b;
  wzDiagonalMetricData& d = *((wzDiagonalMetricData*)(&data));
  for(i=0;i<wzPointDim;i++) d.g_ii[i] = G_ii[i];
  wzRangeLoop(rlist,it){
    b = refine[it].box;
    for(i=0;i<wzPointDim;i++){
      if(inBox(b,p)){
	for(i=0;i<wzPointDim;i++){
	  if(d.g_ii[i]<refine[it].dist[i]) d.g_ii[i] = refine[it].dist[i];
	}
      }
    }
  }
}

wzIndex CogenOctree::Point(wzPoint& p0) const
{
  wzFloat Y[wzPointDim];
  int i,l;
  wzIndex r = DefaultRegion;
  try{
    y(Y,p0);
    wzRangeLoop(blist,l){
      CogenOctreeBox& d = *(box+l);
      for(i=0;i<wzPointDim;i++){
	if(d.min[i]>Y[i]) goto next;
	if(d.max[i]<Y[i]) goto next;
      }
      r = d.region;
    next:
      continue;
    }
    p0.segment()=wzRegion(r);
  }catch(...){
    p0.segment()=DefaultRegion;
  }
  return cogRCRegionFound;
}

cogIndex CogenOctree::BoundaryCondition(cogFlag1& f) const
{
  wzFloat Y[wzPointDim];
  int i,l;
  wzFace ff = DefaultFace;
  try{
    y(Y,f.p1);
    wzRangeLoop(flist,l){
      CogenOctreeFace& d = *(face+l);
      for(i=0;i<wzPointDim;i++){
	if(d.min[i]>Y[i]) goto next;
	if(d.max[i]<Y[i]) goto next;
      }
      ff = d.face;
    next:
      continue;
    }
  }catch(...){
    ff = DefaultFace;
  }
  f.p1.segment() = ff;
  return cogRCConditionFound;
}

wzIndex CogenOctree::Line (cogFlag1& f, const cogLine& s) const
{
  wzIndex rc = Cogeometry::Line(f,s);
  if(rc != cogRCFaceFound) return rc;
  BoundaryCondition(f);
  return cogRCFaceFound;
}

wzpoints CogenOctree::generatePoints(cogeometry g,wzmetric r,wzchart c) const
{
  wzFloat rel = 1.e-3;
  wzpoints plist = new wzPointList;
  ibgoctree gg  = ibgOctreeCreate((wzTensorGrid *)this,g,r,c);
  gg->setMinimalDistance(rel*(max[0]-min[0]),rel*(max[1]-min[1]),rel*(max[2]-min[2]));
  if(boundaryLevel<2){
    gg->generateWithoutEdges();
  }else{
    gg->generate();
  }
  mark(gg,g->Delta);
  ibgGetPoints(plist,gg);
  return plist;
}

wzFloat CogenOctree::chi(const wzPoint& p) const
{
  for(int i=0;i<wzPointDim;i++){
    if(p[i] < min[i]-epsilon)	return -1;
    if(p[i] > max[i]+epsilon) 	return -1;
  }
  return 1;
}

void CogenOctree::getMetric(wzMetricData& data, const cogFlag1& f) const
{
  wzDiagonalMetricSimple::getMetric(data,f);
}


// obsolete:

#include "ibggenerator.hxx"

wzgrid ibg3Generator::create(cogeometry g,wztensorgrid box,wzmetric r,wzchart c)
{
  wzFloat rel = 1.e-3;
  wzpoints plist = new wzPointList; 
  wzFloat min[]={0,0,0};
  wzFloat max[]={0,0,0};
  box->endInitialization(min,max);
  ibgoctree gg  = ibgOctreeCreate(box,g,r,c);
  gg->setMinimalDistance(rel*(max[0]-min[0]),rel*(max[1]-min[1]),rel*(max[2]-min[2]));
  gg->generate();
  //  mark(gg,g->Delta);
  ibgGetPoints(plist,gg);
  Cogenerator gen;
  return gen.generateGrid(g,plist);
}

⌨️ 快捷键说明

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