meshquad.cpp

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

CPP
944
字号
	     // get the Info on background mesh 	     Real8 s =        newVertexOnBThEdge[kvb];	     Vertex &  bv0  = newVertexOnBThEdge[kvb][0];	     Vertex &  bv1  = newVertexOnBThEdge[kvb][1];	     // compute the metrix of the new points 	     vertices[k].m =  Metric(1-s,bv0,s,bv1); 	     kvb++;	     // cout << " ie = " << ie <<"  v0 = " <<  Number(newedges[ie][0]) << endl;	    }	  else 	    {	      ong=Gh.ProjectOnCurve(edges[i],				    0.5,vertices[k],newVerticesOnGeomEdge[kvg++]);	      // vertices[k].i = toI2( vertices[k].r);	      vertices[k].ReferenceNumber = edges[i].ref;	      vertices[k].DirOfSearch = NoDirOfSearch;	      vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);	      	    }  	}      else // straigth line edge ---	{ 	  vertices[k].r = ((R2) edges[i][0] + (R2)  edges[i][1] )*0.5;	  vertices[k].m =  Metric(0.5,edges[i][0],0.5,edges[i][1]);	  vertices[k].on = 0;	}      //vertices[k].i = toI2( vertices[k].r);      R2 AB =  vertices[k].r;      R2 AA = (A+AB)*0.5;      R2 BB = (AB+B)*0.5;      vertices[k].ReferenceNumber = edges[i].ref;	    vertices[k].DirOfSearch = NoDirOfSearch;	          newedges[ie].on = Gh.Contening(AA,ong);      newedges[ie++].v[1]=vertices+k;      newedges[ie]=edges[i];      newedges[ie].adj[0]=newedges + ie -1;      newedges[ie].adj[1]=newedges+(edges[i].adj[1]-edges) ;      newedges[ie].on =  Gh.Contening(BB,ong);      newedges[ie++].v[0]=vertices+k;      // cout << " ie = " << ie-2 << " vm " << k << " v0 = " <<  Number(newedges[ie-2][0])      //	   << " v1 = " << Number(newedges[ie-1][1])        //	   << " ong =" << ong-Gh.edges       //	   << " on 0 =" <<  newedges[ie-2].on -Gh.edges << AA      //	   << " on 1 =" <<  newedges[ie-1].on -Gh.edges << BB       //	   << endl;      k++;    }#ifdef DEBUG  assert(kvb ==  newNbVertexOnBThEdge);  // verif edge   { Vertex *v0 = vertices, *v1 = vertices+ k;    for (Int4  i=0;i<ie;i++)     {       assert( &newedges[i][0] >= v0 &&  &newedges[i][0] < v1);       assert( &newedges[i][1] >= v0 &&  &newedges[i][1] < v1);     }  }#endif  if (edgesGtoB) delete [] edgesGtoB;  edgesGtoB=0;  newnbv=k;  newNbVerticesOnGeomEdge=kvg;  if (newnbv> nbvx) goto Error;// bug       nbv = k;  kedge = new Int4[3*nbt+1];  ksplitarray = new Int4[nbt+1];  ksplit = ksplitarray +1; // because ksplit[-1] == ksplitarray[0]   for (i=0;i<3*nbt;i++)    kedge[i]=-1;  //   for (i=0;i<nbt;i++)   {       Triangle & t = triangles[i];     assert(t.link);     for(int j=0;j<3;j++)       {	 const TriangleAdjacent ta = t.Adj(j);	 const Triangle & tt = ta;	 if (&tt >= lastT)	   t.SetAdj2(j,0,0);// unset adj	 const Vertex & v0 = t[VerticesOfTriangularEdge[j][0]];	 const Vertex & v1 = t[VerticesOfTriangularEdge[j][1]];	 Int4  ke =edge4->findtrie(Number(v0),Number(v1));	 if (ke>0) 	   {	     Int4 ii = Number(tt);	     int  jj = ta;	     Int4 ks = ke + nbvold;	     kedge[3*i+j] = ks;	     if (ii<nbt) // good triangle	       kedge[3*ii+jj] = ks;	     Vertex &A=vertices[ks];	     Real8 aa,bb,cc,dd;	     if ((dd=Area2(v0.r,v1.r,A.r)) >=0)	       { // warning PB roundoff error 		 if (t.link && ( (aa=Area2( A.r    , t[1].r , t[2].r )) < 0.0 				||   (bb=Area2( t[0].r , A.r    , t[2].r )) < 0.0  				||   (cc=Area2( t[0].r , t[1].r , A.r    )) < 0.0))		   ferr++, cerr << " Error : " <<  ke + nbvold << " not in triangle " 				<< i << " In=" << !!t.link				<< " " <<  aa  << " " << bb << " " << cc << " " << dd << endl;		 	       }	     	     else	       {		 if (tt.link && ( (aa=Area2( A.r     , tt[1].r , tt[2].r )) < 0 				 ||   (bb=Area2( tt[0].r , A.r     , tt[2].r )) < 0 				 ||   (cc=Area2( tt[0].r , tt[1].r , A.r     )) < 0)) 		   ferr++, cerr << " Warning : " <<  ke + nbvold << " not in triangle " << ii 				<< " In=" << !!tt.link 				<< " " <<  aa  << " " << bb << " " << cc << " " << dd << endl;					       } 	     	   }       }   }  if(ferr)    {      cerr << " Number of triangles with P2 interpolation Probleme " << ferr << endl;;      MeshError(9);    }  for (i=0;i<nbt;i++)    {      ksplit[i]=1; // no split by default      const Triangle & t = triangles[ i];      // cout << " Triangle " << i << " " << t  << !!t.link << ":: " ;      int nbsplitedge =0;      int nbinvisible =0;      int invisibleedge=0;      int kkk[3];            for (int j=0;j<3;j++)	{	  if (t.Hidden(j)) invisibleedge=j,nbinvisible++;	  	  const TriangleAdjacent ta = t.Adj(j);	  const Triangle & tt = ta;	  	  const Vertex & v0 = t[VerticesOfTriangularEdge[j][0]];	  const Vertex & v1 = t[VerticesOfTriangularEdge[j][1]];	 //  cout << " ke = " << kedge[3*i+j]  << " " << Number(v0) << " " << Number(v1) << "/ ";	  if ( kedge[3*i+j] < 0) 	    {	      Int4  ke =edge4->findtrie(Number(v0),Number(v1));	      //  cout << ":" << ke << "," << !!t.link << " " <<  &tt ;	      if (ke<0) // new 		{		  if (&tt) // internal triangles all the boundary 		      { // new internal edges 			Int4 ii = Number(tt);			int  jj = ta;	      			kedge[3*i+j]=k;// save the vertex number 			kedge[3*ii+jj]=k;			if (k<nbvx) 			  {			    vertices[k].r = ((R2) v0+(R2) v1 )/2;			    //vertices[k].i = toI2( vertices[k].r);			    vertices[k].ReferenceNumber=0;	        vertices[k].DirOfSearch =NoDirOfSearch;			    vertices[k].m =  Metric(0.5,v0,0.5,v1);			  }			k++;			kkk[nbsplitedge++]=j;		      		    } // tt 		  else		    cerr <<endl <<  " Bug " <<i<< " " << j << " t=" << t << endl;		  		} // ke<0	       	      else		{ // ke >=0		  kedge[3*i+j]=nbvold+ke;		  kkk[nbsplitedge++]=j;// previously splited		}	    }	  else 	    kkk[nbsplitedge++]=j;// previously splited	  	}       assert (nbinvisible<2);     // cout << " " <<  nbinvisible << " " <<  nbsplitedge << endl;      switch (nbsplitedge) {      case 0: ksplit[i]=10; newnbt++; break;   // nosplit      case 1: ksplit[i]=20+kkk[0];newnbt += 2; break; // split in 2       case 2: ksplit[i]=30+3-kkk[0]-kkk[1];newnbt += 3; break; // split in 3       case 3:	if (nbinvisible) ksplit[i]=40+invisibleedge,newnbt += 4;	else   ksplit[i]=10*nfortria,newnbt+=nfortria;	break;      }     assert(ksplit[i]>=40);    }  //  now do the element split  newNbOfQuad = 4*NbOfQuad;  nbv = k;#ifdef DRAWING2    inquire();#endif  //  cout << " Nbv = " << nbv << endl;  kkk = nbt;  ksplit[-1] = nbt;  // look on  old true  triangles   for (i=0;i<nbtsave;i++)    {      //     cout << "Triangle " << i << " " << ksplit[i] << ":" << triangles[i]      //	   << " ----------------------------------------------- " <<endl;      // Triangle * tc=0;      int  nbmkadj=0;      Int4 mkadj [100];      mkadj[0]=i;      Int4 kk=ksplit[i]/10;      int  ke=(int) (ksplit[i]%10);      assert(kk<7 && kk >0);            // def the numbering   k (edge) i vertex       int k0 = ke;      int k1 = NextEdge[k0];      int k2 = PreviousEdge[k0];      int i0 = OppositeVertex[k0];      int i1 = OppositeVertex[k1];      int i2 = OppositeVertex[k2];              Triangle &t0=triangles[i];       Vertex * v0=t0(i0);                  Vertex * v1=t0(i1);                  Vertex * v2=t0(i2);       // cout << "nbmkadj " << nbmkadj << " it=" << i <<endl;       assert(nbmkadj< 10);       // --------------------------       TriangleAdjacent ta0(t0.Adj(i0)),ta1(t0.Adj(i1)),ta2(t0.Adj(i2));       // save the flag Hidden       int hid[]={t0.Hidden(0),t0.Hidden(1),t0.Hidden(2)};       // un set all adj -- save Hidden flag --       t0.SetAdj2(0,0,hid[0]);       t0.SetAdj2(1,0,hid[1]);       t0.SetAdj2(2,0,hid[2]);       // --  remake        switch  (kk) {       case 1: break;// nothing        case 2: // 	 {	   Triangle &t1=triangles[kkk++];	   t1=t0;	   assert (kedge[3*i+i0]>=0);	   Vertex * v3 = vertices + kedge[3*i+k0];	   	   t0(i2) = v3;	   t1(i1) = v3;	   t0.SetAllFlag(k2,0);	   t1.SetAllFlag(k1,0);	 } 	 break;        case 3: //	 {	   Triangle &t1=triangles[kkk++];            Triangle &t2=triangles[kkk++];            t2=t1=t0;            assert (kedge[3*i+k1]>=0);            assert (kedge[3*i+k2]>=0);                        Vertex * v01 = vertices + kedge[3*i+k2];            Vertex * v02 = vertices + kedge[3*i+k1];             t0(i1) = v01;             t0(i2) = v02;             t1(i2) = v02;            t1(i0) = v01;             t2(i0) = v02; 	    t0.SetAllFlag(k0,0);	    t1.SetAllFlag(k1,0);	    t1.SetAllFlag(k0,0);	    t2.SetAllFlag(k2,0);	 } 	 break;       case 4: //        case 6: // split in 4 	 {	   Triangle &t1=triangles[kkk++];	   Triangle &t2=triangles[kkk++];	   Triangle &t3=triangles[kkk++];	   t3=t2=t1=t0;	   assert(kedge[3*i+k0] >=0 && kedge[3*i+k1] >=0 && kedge[3*i+k2] >=0);	   Vertex * v12 = vertices + kedge[3*i+k0];	   Vertex * v02 = vertices + kedge[3*i+k1]; 	   Vertex * v01 = vertices + kedge[3*i+k2];	   // cout << Number(t0(i0))  << " " << Number(t0(i1)) 	   //     << " " <<  Number(t0(i2)) 	   //     << " " <<  kedge[3*i+k0] 	   //     << " " <<  kedge[3*i+k1] 	   //     << " " <<  kedge[3*i+k2] << endl;	   t0(i1) = v01;	   t0(i2) = v02;	   t0.SetAllFlag(k0,hid[k0]);	   t1(i0) = v01;	   t1(i2) = v12;	   t0.SetAllFlag(k1,hid[k1]);	   	   t2(i0) = v02;	   t2(i1) = v12;	   t2.SetAllFlag(k2,hid[k2]);	   	   t3(i0) = v12;	   t3(i1) = v02;	   t3(i2) = v01;	   	   	   t3.SetAllFlag(0,hid[0]);	   	   t3.SetAllFlag(1,hid[1]);	   	   t3.SetAllFlag(2,hid[2]);	   if ( kk == 6)	     {	       	       Triangle &t4=triangles[kkk++];	       Triangle &t5=triangles[kkk++];	       	       t4 = t3;	       t5 = t3;	       t0.SetHidden(k0);	       t1.SetHidden(k1);	       t2.SetHidden(k2);	       t3.SetHidden(0);	       t4.SetHidden(1);	       t5.SetHidden(2);	       		if (nbv < nbvx ) 		  {		    vertices[nbv].r = ((R2) *v01 + (R2) *v12  + (R2) *v02 ) / 3.0;		    vertices[nbv].ReferenceNumber =0;	      vertices[nbv].DirOfSearch =NoDirOfSearch;		    //vertices[nbv].i = toI2(vertices[nbv].r);		    Real8 a3[]={1./3.,1./3.,1./3.};		    vertices[nbv].m = Metric(a3,v0->m,v1->m,v2->m);		    Vertex * vc =  vertices +nbv++;		    t3(i0) = vc;		    t4(i1) = vc;		    t5(i2) = vc;		  }		else		  goto Error; 	     }		    	 } 	 break;                }        // cout << " -- " << i << " " << nbmkadj << " " << kkk << " " << tc << endl;       //  t0.SetDetf();       // save all the new triangles       mkadj[nbmkadj++]=i;       Int4 jj;       if (t0.link) 	 for (jj=nbt;jj<kkk;jj++)	   {	     triangles[jj].link=t0.link;	     t0.link= triangles+jj;	     mkadj[nbmkadj++]=jj;	     // triangles[jj].SetDet();	   }       // cout << " -- " << i << " " << nbmkadj << endl;       assert(nbmkadj<=13);// 13 = 6 + 4 + 3         if (kk==6)  newNbOfQuad+=3;	 //	 triangles[i].Draw();              for (jj=ksplit[i-1];jj<kkk;jj++)	 // triangles[jj].SetDet();       //	   triangles[jj].Draw();	        nbt = kkk;       ksplit[i]= nbt; // save last adresse of the new triangles       kkk = nbt;           }//  cout << " nv = " << nbv << " nbt = " << nbt << endl;  for (i=0;i<nbv;i++)    vertices[i].m = vertices[i].m*2.;  //  if(withBackground)    for (i=0;i<BTh.nbv;i++)      BTh.vertices[i].m =  BTh.vertices[i].m*2.;#ifdef DRAWING2  Draw();  inquire();#endif      ret = 2;  if (nbt>= nbtx) goto Error; // bug   if (nbv>= nbvx) goto Error; // bug   // generation of the new triangles   SetIntCoor("In SplitElement");   ReMakeTriangleContainingTheVertex();  if(withBackground)    BTh.ReMakeTriangleContainingTheVertex();  delete [] edges;  edges = newedges;  nbe = newnbe;  NbOfQuad = newNbOfQuad;  for (i=0;i<NbSubDomains;i++)    {       Int4 k = subdomains[i].edge- edges;      subdomains[i].edge =  edges+2*k; // spilt all edge in 2     }      if (ksplitarray) delete [] ksplitarray;  if (kedge) delete [] kedge;  if (edge4) delete edge4;  if (VerticesOnGeomEdge) delete [] VerticesOnGeomEdge;  VerticesOnGeomEdge= newVerticesOnGeomEdge;  if(VertexOnBThEdge) delete []  VertexOnBThEdge;  VertexOnBThEdge = newVertexOnBThEdge;  NbVerticesOnGeomEdge = newNbVerticesOnGeomEdge;  NbVertexOnBThEdge=newNbVertexOnBThEdge;  //  ReMakeTriangleContainingTheVertex();  FillHoleInMesh();#ifdef DEBUG  for (i=0;i<nbt;i++)    triangles[i].check();#endif   if (verbosity>2)   cout << "    (out) Nb of Quadrilaterals = " << NbOfQuad 	<< " Nb Of Triangles = " << nbt-NbOutT- NbOfQuad*2 	<< " Nb of outside triangles = " << NbOutT << endl; CurrentTh=OCurrentTh; return 0; //ok Error:  nbv = nbvold;  nbt = nbtold;  NbOutT = NbOutTold;  // cleaning memory ---  delete newedges;  if (ksplitarray) delete [] ksplitarray;  if (kedge) delete [] kedge;  if (newVerticesOnGeomEdge) delete [] newVerticesOnGeomEdge;  if (edge4) delete edge4;  if(newVertexOnBThEdge) delete []  newVertexOnBThEdge;    CurrentTh= OCurrentTh;  return ret; // ok }} //  end of namespcae bamg 

⌨️ 快捷键说明

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