4894
Mesh3 * truncmesh(const Mesh3 &Th,const long &kksplit,int *split, bool kk, const int newbelabel){
4896
static const int FaceTriangle[4]={3,0,1,2}; //={{3,2,1}, {0,2,3},{ 3,1,0},{ 0,1,2}}
4899
// computation of number of border elements and vertex without split
4908
const int kksplit2 = kksplit*kksplit;
4909
const int kksplit3 = kksplit2*kksplit;
4910
int tagb[4]={1,2,4,8} ;
4911
KN<int> tagTonB(Th.nt);
4914
for( int ibe=0; ibe < Th.nbe; ibe++)
4922
Mesh3 * truncmesh(const Mesh3 &Th,const long &kksplit,int *split, bool kk, const int newbelabel)
4925
static const int FaceTriangle[4]={3,0,1,2}; //={{3,2,1}, {0,2,3},{ 3,1,0},{ 0,1,2}}
4928
// computation of number of border elements and vertex without split
4938
const int kksplit2 = kksplit*kksplit;
4939
const int kksplit3 = kksplit2*kksplit;
4941
int tagb[4]={1,2,4,8} ;
4942
KN<int> tagTonB(Th.nt);
4945
for( int ibe=0; ibe < Th.nbe; ibe++)
4917
4948
int it=Th.BoundaryElement(ibe,iff);
4918
4949
tagTonB[it]|= tagb[iff];
4919
int ifff=iff,itt=Th.ElementAdj(it,ifff);
4950
int ifff=iff,itt=Th.ElementAdj(it,ifff);
4920
4951
if(itt >=0 && itt != it)
4921
tagTonB[itt]|= tagb[ifff];
4924
for (int i=0;i<Th.nt;i++)
4927
// computation of number of tetrahedrons
4929
// computation of number of border elements
4930
for (int j=0;j<4;j++)
4932
int jt=j,it=Th.ElementAdj(i,jt);
4933
if ( (it==i || it <0) || ! split[it]) nbeee++;
4934
if(it==i || it <0) nbe += kksplit2; //on est sur la frontiere
4935
else if (!split[it]) nbe += kksplit2; //le voisin ne doit pas etre decoupe
4936
else if ( (tagTonB[i]&tagb[j] ) != 0 && i<it) nbe += kksplit2; // internal boundary ..
4943
for (int e=0;e<6;e++){
4944
hmin=min(hmin,Th[i].lenEdge(e)); // calcul de .lenEdge pour un Mesh3
4948
cout << " number of not intern boundary faces = " << nbeee << ", all faces = " << nbe << endl;
4949
double hseuil = (hmin/kksplit)/10.;
4951
/* determination de bmin, bmax et hmin */
4953
KN<int> takevertex(Th.nv);
4954
for(int i=0; i<Th.nv; i++){
4957
for(int i=0; i<Th.nt; i++){
4959
const Tet &K(Th.elements[i]);
4961
for(int ii=0; ii<4; ii++){
4962
int iv= Th.operator()( K[ii] );
4963
if( takevertex[iv] == -1 ){
4964
R3 P( Th.vertices[iv].x, Th.vertices[iv].y, Th.vertices[iv].z);
4967
takevertex[iv]=nvtrunc;
4976
KN<int> NbFois(nvtrunc,0);
4977
for(int i=0; i<nvtrunc; i++)
4980
for(int i=0; i<Th.nt; i++){
4982
const Tet &K(Th.elements[i]);
4983
for(int e=0; e<6; e++){
4984
int e1 = Th.operator()( K[ Th[i].nvedge[e][0] ] );
4985
int e2 = Th.operator()( K[ Th[i].nvedge[e][1] ] );
4987
if( takevertex[e1] < takevertex[e2] ){
4988
NbFois[ takevertex[e1] ]++;
4992
NbFois[ takevertex[e2] ]++;
5000
KN<int> first(nvtrunc+1,0);
5001
KN<int> current(nvtrunc,0);
5002
for(int i=1; i<nvtrunc; i++)
5003
first[i] = first[i-1] + NbFois[i-1];
5005
first[nvtrunc] = majedge;
5006
for(int i=0; i<nvtrunc; i++)
5007
current[i] = first[i];
5009
cout << " trunc (3d) majedge =" << majedge << endl;
5011
KN<int> tableau(majedge);
5012
for(int i=0; i<Th.nt; i++){
5014
const Tet &K(Th.elements[i]);
5015
for(int e=0; e<6; e++){
5016
int e1 = Th.operator()( K[ Th[i].nvedge[e][0] ] );
5017
int e2 = Th.operator()( K[ Th[i].nvedge[e][1] ] );
5018
//int e1 = Th[i].nvedge[e][0];
5019
//int e2 = Th[i].nvedge[e][1];
5021
if( takevertex[e1] < takevertex[e2] ){
5022
tableau[ current[ takevertex[e1] ] ] = takevertex[e2];
5023
current[ takevertex[e1] ]++;
5026
tableau[ current[ takevertex[e2] ] ] = takevertex[e1];
5027
current[ takevertex[e2] ]++;
5033
for(int i=0; i<nvtrunc; i++)
5034
assert(current[i] == first[i+1]);
5036
// determination du nombre d'edge
5038
for(int i=0; i<nvtrunc; i++){
5040
list<int>::const_iterator ilist;
5041
//cout << "i = "<< i << " nvtrunc = " << nvtrunc << endl;
5042
for(int jj=first[i]; jj < first[i+1]; jj++){
5044
//cout << "tableauu[ jj ] = " << tableau[ jj ] << endl;
5045
for( ilist=list1.begin(); ilist!=list1.end(); ilist++){
5046
if( *ilist == tableau[ jj ] ){ labOk = 1; break; }
5049
list1.push_back(tableau[jj]);
5050
//cout << "push back :: tableauu[ jj ] = " << tableau[ jj ] << endl;
5055
//cout << " nbedge="<< nbedge << endl;
5061
/* determination des vertex, triangles et tetrah�dre obtenue apr�s splitting dans le Simplex */
5063
int nfacesub = kksplit2;
5064
int ntetsub = kksplit3;
5065
int nvsub = (kksplit+1)*(kksplit+2)*(kksplit+3)/6;
5066
int ntrisub = 4*kksplit2;
5068
R3 *vertexsub; //[nvsub];
5069
int *tetsub; //[4*ntetsub];
5070
int *trisub; //[4*kksplit*kksplit];
5072
SplitSimplex<R3>( kksplit, nvsub, vertexsub, ntetsub, tetsub);
5073
SplitSurfaceSimplex( kksplit, ntrisub, trisub);
5076
for( int iii=0; iii< nvsub; iii++){
5077
cout << "vertexsub["<< iii <<"]=" << " "<< vertexsub[iii].x << " "<< vertexsub[iii].y << " "<< vertexsub[iii].z << endl;
5079
for( int iii=0; iii< ntetsub; iii++){
5080
cout << "tetsub=" << tetsub[4*iii] << " "<< tetsub[4*iii+1] << " "<< tetsub[4*iii+2] << " "<< tetsub[4*iii+3] <<endl;
5083
for( int iii=0; iii< 4*kksplit2; iii++){
5084
cout << iii << " tetsub=" << trisub[3*iii] << " "<< trisub[3*iii+1] << " " << trisub[3*iii+2] << endl;
5088
cout << " -- trunc (3d) : Th.nv= " << Th.nv << "kksplit="<< kksplit << endl;
5089
// determination de nv
4952
tagTonB[itt]|= tagb[ifff];
4955
for (int i=0;i<Th.nt;i++)
4959
// computation of number of tetrahedrons
4961
// computation of number of border elements
4962
for (int j=0;j<4;j++)
4964
int jt=j,it=Th.ElementAdj(i,jt);
4965
if ( (it==i || it <0) || ! split[it]) nbeee++;// boundary face ...
4966
else nbfi++; // internal face count 2 times ...
4967
if(it==i || it <0) nbe += kksplit2; //on est sur la frontiere
4968
else if (!split[it]) nbe += kksplit2; //le voisin ne doit pas etre decoupe
4969
else if ( (tagTonB[i]&tagb[j] ) != 0 && i<it) nbe += kksplit2; // internal boundary ..
4972
for (int e=0;e<6;e++){
4973
hmin=min(hmin,Th[i].lenEdge(e)); // calcul de .lenEdge pour un Mesh3
4976
ffassert( nbfi %2 ==0) ;
4977
nface = nbeee + nbfi/2;
4978
double hseuil = (hmin/kksplit)/1000.;
4980
cout << " number of not intern boundary faces = " << nbeee << ", all faces = " << nbe << ", hseuil=" << hseuil <<endl;
4982
/* determination de bmin, bmax et hmin */
4984
KN<int> takevertex(Th.nv,-1);
4986
for(int i=0; i<Th.nt; i++){
4989
const Tet &K(Th.elements[i]);
4990
for(int ii=0; ii<4; ii++)
4992
int iv= Th.operator()( K[ii] );
4993
if( takevertex[iv] == -1 )
4995
bmin=Minc(Th.vertices[iv],bmin);
4996
bmax=Maxc(Th.vertices[iv],bmax);
4997
takevertex[iv]=nvtrunc++;
5005
{ // compute the number of slip edge ...
5007
HashTable<SortArray<int,2>,int> edges(3*nface,nface);
5008
for(int i=0; i<Th.nt; i++){
5011
const Tet &K(Th.elements[i]);
5012
for(int e=0;e<6;++e)
5015
int e1 = Th( K[ Th[i].nvedge[e][0] ] );
5016
int e2 = Th( K[ Th[i].nvedge[e][1] ] );
5017
SortArray<int,2> key(e1,e2);
5018
if(!edges.find(key) )
5019
edges.add(key,nedge++);
5024
if(verbosity>10) cout << " -- nvertex " << nvtrunc << ", nedges = "<< nedge
5025
<< ", nfaces = " << nface << " ntet =" << ntsplit
5027
<< " -- Euler/Poincare constante = " << nvtrunc-nedge+nface-ntsplit
5030
/* determination des vertex, triangles et tetrahedre obtenue apres splitting dans le Simplex */
5032
int nfacesub = kksplit2;
5033
int ntetsub = kksplit3;
5034
int nvsub = (kksplit+1)*(kksplit+2)*(kksplit+3)/6;
5035
int ntrisub = 4*kksplit2;
5037
R3 *vertexsub; //[nvsub];
5038
int *tetsub; //[4*ntetsub];
5039
int *trisub; //[4*kksplit*kksplit];
5041
SplitSimplex<R3>( kksplit, nvsub, vertexsub, ntetsub, tetsub);
5042
SplitSurfaceSimplex( kksplit, ntrisub, trisub);
5045
cout << " -- trunc (3d) : Th.nv= " << Th.nv << "kksplit="<< kksplit << endl;
5094
5047
int ntnosplit = nt/kksplit3;
5095
5048
int nbenosplit = nbe/kksplit2;
5096
5049
int nfacenosplit = (4*ntnosplit+nbenosplit)/2;
5098
5051
if(verbosity>100) cout << " 1) nv= " << nv << endl;
5099
5052
nv = nv + nfacenosplit*( (kksplit+1)*(kksplit+2)/2 - 3*(kksplit-1) -3 );
5100
5053
if(verbosity>100) cout << " 2) nv= " << nv << endl;
5101
nv = nv + nbedge*( kksplit-1 );
5054
nv = nv + nedge*( kksplit-1 );
5102
5055
if(verbosity>100) cout << " 3) nv= " << nv << endl;
5103
5056
nv = nv + nvtrunc;
5104
5057
if(verbosity>100) cout << " 4) nv= " << nv << endl;
5112
Vertex3 *v=new Vertex3[nv];
5113
Tet *t = new Tet[nt];
5116
Triangle3 *b = new Triangle3[nbe];
5119
EF23::GTree<Vertex3> *gtree = new EF23::GTree<Vertex3>(v,bmin,bmax,0);
5122
for(int i=0; i<Th.nt; i++){
5124
const Tet &K(Th.elements[i]);
5126
for(int ii=0; ii< 4; ii++){
5127
ivv[ii] =Th.operator()(K[ii]);
5130
R3 vertextetsub[nvsub];
5131
for( int iv=0; iv<nvsub; iv++){
5132
double alpha=vertexsub[iv].x;
5133
double beta=vertexsub[iv].y;
5134
double gamma=vertexsub[iv].z;
5136
vertextetsub[iv].x = (1-alpha-beta-gamma)*Th.vertices[ivv[0]].x + alpha*Th.vertices[ivv[1]].x + beta*Th.vertices[ivv[2]].x + gamma*Th.vertices[ivv[3]].x;
5137
vertextetsub[iv].y = (1-alpha-beta-gamma)*Th.vertices[ivv[0]].y + alpha*Th.vertices[ivv[1]].y + beta*Th.vertices[ivv[2]].y + gamma*Th.vertices[ivv[3]].y;
5138
vertextetsub[iv].z = (1-alpha-beta-gamma)*Th.vertices[ivv[0]].z + alpha*Th.vertices[ivv[1]].z + beta*Th.vertices[ivv[2]].z + gamma*Th.vertices[ivv[3]].z;
5141
int newindex[nvsub];
5142
for( int iv=0; iv<nvsub; iv++){
5143
const R3 viR3(vertextetsub[iv].x,vertextetsub[iv].y,vertextetsub[iv].z);
5144
const Vertex3 &vi( viR3 );
5145
Vertex3 * pvi=gtree->ToClose(vi,hseuil);
5153
gtree->Add( v[np] );
5157
newindex[iv] = pvi-v;
5161
//newindex[iv] = pvi-v;
5162
if(np>nv) cout << "np=" << np << " nv=" << nv << endl;
5163
ffassert( np <= nv );
5166
for( int ii=0; ii<ntetsub; ii++){
5168
for( int jj=0; jj< 4; jj++){
5169
ivt[jj] = newindex[tetsub[4*ii+jj]];
5170
assert( tetsub[4*ii+jj] < nvsub );
5171
assert( ivt[jj] < np );
5173
(tt++)->set( v, ivt, K.lab);
5175
assert( itt <= nt );
5178
for (int j=0;j<4;j++)
5180
int jt=j,it=Th.ElementAdj(i,jt);
5182
if ( ( (tagTonB[i]&tagb[j]) ==0 ) && !(it==i || it <0) && !split[it])
5184
// new border not on boundary
5187
for( int ii=0; ii<nfacesub; ii++)
5189
int iface = 3*FaceTriangle[j]*nfacesub+3*ii;
5191
for( int jjj=0; jjj<3; jjj++)
5193
ivb[jjj] = newindex[ trisub[iface+jjj] ];
5194
assert( trisub[ iface+jjj ] < nvsub );
5195
assert( ivb[jjj] < np );
5198
(bb++)->set( v, ivb, newbelabel);
5208
cout << " -- Number of new border face not on Border " << ie << endl;
5209
delete [] vertexsub; //[nvsub];
5210
delete [] tetsub; //[4*ntetsub];
5211
delete [] trisub; //[4*kksplit*kksplit];
5213
// split border elements
5214
int nv2Dsub = (kksplit+1)*(kksplit+2)/4;
5215
int ntri2Dsub = kksplit2;
5216
R2 *vertex2Dsub; //[nvsub];
5217
int *tri2Dsub; //[4*kksplit*kksplit];
5219
SplitSimplex<R2>( kksplit, nv2Dsub, vertex2Dsub, ntri2Dsub, tri2Dsub);
5222
for( int ibe=0; ibe < Th.nbe; ibe++)
5225
int it=Th.BoundaryElement(ibe,iff);
5226
int ifff=iff,itt=Th.ElementAdj(it,ifff);
5228
if( split[it] == 0 && split[itt] == 0) continue; // boundary not on one element
5230
const Triangle3 &K(Th.be(ibe));
5233
ivv[0] = Th.operator()(K[0]);
5234
ivv[1] = Th.operator()(K[1]);
5235
ivv[2] = Th.operator()(K[2]);
5237
R3 vertextrisub[nv2Dsub];
5238
for( int iv=0; iv<nv2Dsub; iv++)
5240
double alpha=vertex2Dsub[iv].x;
5241
double beta=vertex2Dsub[iv].y;
5243
vertextrisub[iv].x = (1-alpha-beta)*Th.vertices[ivv[0]].x + alpha*Th.vertices[ivv[1]].x + beta*Th.vertices[ivv[2]].x;
5244
vertextrisub[iv].y = (1-alpha-beta)*Th.vertices[ivv[0]].y + alpha*Th.vertices[ivv[1]].y + beta*Th.vertices[ivv[2]].y;
5245
vertextrisub[iv].z = (1-alpha-beta)*Th.vertices[ivv[0]].z + alpha*Th.vertices[ivv[1]].z + beta*Th.vertices[ivv[2]].z;
5248
int newindex[nv2Dsub];
5249
for( int iv=0; iv<nv2Dsub; iv++)
5251
const Vertex3 &vi( vertextrisub[iv] );
5252
Vertex3 * pvi=gtree->ToClose(vi,hseuil);
5254
newindex[iv] = pvi-v;
5257
for( int ii=0; ii<nfacesub; ii++)
5260
for( int jjj=0; jjj<3; jjj++)
5262
ivb[jjj] = newindex[ tri2Dsub[3*ii+jjj] ];
5263
assert( tri2Dsub[ 3*ii+jjj ] < nvsub );
5264
if(verbosity > 4 ) cout << " " << ivb[jjj] << " np:" << np<< endl;
5265
assert( ivb[jjj] < np );
5268
(bb++)->set( v, ivb, K.lab);
5276
delete [] vertex2Dsub; //[4*ntetsub];
5277
delete [] tri2Dsub; //[4*kksplit*kksplit];
5282
cout << "nbofv initial" << Th.nv << endl;
5283
cout << "nv=" << nv << " np=" << np << endl;
5284
cout << "itt=" << itt << " nt=" << nt << endl;
5285
cout << "ie=" << ie << " nbe=" << nbe << endl;
5287
ffassert( nv == np );
5288
ffassert( ie ==nbe);
5289
ffassert( itt == nt );
5293
Mesh3 *Tht = new Mesh3( nv, nt, nbe, v, t, b);
5294
Tht->BuildGTree(); // Add JM. Oct 2010
5065
Vertex3 *v=new Vertex3[nv];
5066
Tet *t = new Tet[nt];
5069
Triangle3 *b = new Triangle3[nbe];
5071
R3 hh = (bmax-bmax)/10.;
5072
EF23::GTree<Vertex3> *gtree = new EF23::GTree<Vertex3>(v,bmin-hh,bmax+hh,0);
5074
int np=0; // nb of new points ..
5077
KN<R3> vertextetsub(nvsub);
5078
KN<int> newindex (nvsub);
5080
for(int i=0; i<Th.nt; i++)
5083
const Tet &K(Th.elements[i]);
5085
for(int ii=0; ii< 4; ii++)
5088
for( int iv=0; iv<nvsub; iv++)
5089
(R3&) vertextetsub[iv]= vertexsub[iv].Bary(pP);
5091
for( int iv=0; iv<nvsub; iv++)
5093
Vertex3 * pvi=gtree->ToClose(vertextetsub[iv],hseuil);
5097
(R3&) v[np] = vertextetsub[iv];
5100
gtree->Add( v[np] );
5104
newindex[iv] = pvi-v;
5106
ffassert( np <= nv );
5109
for( int ii=0; ii<ntetsub; ii++)
5112
for( int jj=0; jj< 4; jj++)
5114
ivt[jj] = newindex[tetsub[4*ii+jj]];
5115
assert( tetsub[4*ii+jj] < nvsub );
5116
assert( ivt[jj] < np );
5118
(tt++)->set( v, ivt, K.lab);
5120
assert( itt <= nt );
5123
for (int j=0;j<4;j++)
5125
int jt=j,it=Th.ElementAdj(i,jt);
5127
if ( ( (tagTonB[i]&tagb[j]) ==0 ) && !(it==i || it <0) && !split[it])
5129
// new border not on boundary
5132
for( int ii=0; ii<nfacesub; ii++)
5134
int iface = 3*FaceTriangle[j]*nfacesub+3*ii;
5136
for( int jjj=0; jjj<3; jjj++)
5138
ivb[jjj] = newindex[ trisub[iface+jjj] ];
5139
assert( trisub[ iface+jjj ] < nvsub );
5140
assert( ivb[jjj] < np );
5143
(bb++)->set( v, ivb, newbelabel);
5153
cout << " ++ np=" << np << "== nv=" << nv << endl;
5154
ffassert( np == nv);
5156
cout << " -- Number of new border face not on Border " << ie << endl;
5157
delete [] vertexsub; //[nvsub];
5158
delete [] tetsub; //[4*ntetsub];
5159
delete [] trisub; //[4*kksplit*kksplit];
5161
// split border elements
5162
int nv2Dsub = (kksplit+1)*(kksplit+2)/4;
5163
int ntri2Dsub = kksplit2;
5164
R2 *vertex2Dsub; //[nvsub];
5165
int *tri2Dsub; //[4*kksplit*kksplit];
5167
SplitSimplex<R2>( kksplit, nv2Dsub, vertex2Dsub, ntri2Dsub, tri2Dsub);
5170
for( int ibe=0; ibe < Th.nbe; ibe++)
5173
int it=Th.BoundaryElement(ibe,iff);
5174
int ifff=iff,itt=Th.ElementAdj(it,ifff);
5176
if( split[it] == 0 && split[itt] == 0) continue; // boundary not on one element
5178
const Triangle3 &K(Th.be(ibe));
5181
ivv[0] = Th.operator()(K[0]);
5182
ivv[1] = Th.operator()(K[1]);
5183
ivv[2] = Th.operator()(K[2]);
5185
R3 *vertextrisub = new R3 [nv2Dsub];
5186
int *newindex = new int[nv2Dsub];
5187
for( int iv=0; iv<nv2Dsub; iv++)
5189
double alpha=vertex2Dsub[iv].x;
5190
double beta=vertex2Dsub[iv].y;
5192
vertextrisub[iv].x = (1-alpha-beta)*Th.vertices[ivv[0]].x + alpha*Th.vertices[ivv[1]].x + beta*Th.vertices[ivv[2]].x;
5193
vertextrisub[iv].y = (1-alpha-beta)*Th.vertices[ivv[0]].y + alpha*Th.vertices[ivv[1]].y + beta*Th.vertices[ivv[2]].y;
5194
vertextrisub[iv].z = (1-alpha-beta)*Th.vertices[ivv[0]].z + alpha*Th.vertices[ivv[1]].z + beta*Th.vertices[ivv[2]].z;
5198
for( int iv=0; iv<nv2Dsub; iv++)
5200
const Vertex3 &vi( vertextrisub[iv] );
5201
Vertex3 * pvi=gtree->ToClose(vi,hseuil);
5203
newindex[iv] = pvi-v;
5206
for( int ii=0; ii<nfacesub; ii++)
5209
for( int jjj=0; jjj<3; jjj++)
5211
ivb[jjj] = newindex[ tri2Dsub[3*ii+jjj] ];
5212
assert( tri2Dsub[ 3*ii+jjj ] < nvsub );
5213
if(verbosity > 199 ) cout << " " << ivb[jjj] << " np:" << np<< endl;
5214
assert( ivb[jjj] < np );
5217
(bb++)->set( v, ivb, K.lab);
5221
delete [] vertextrisub;
5227
delete [] vertex2Dsub; //[4*ntetsub];
5228
delete [] tri2Dsub; //[4*kksplit*kksplit];
5233
cout << "nbofv initial" << Th.nv << endl;
5234
cout << "nv=" << nv << " np=" << np << endl;
5235
cout << "itt=" << itt << " nt=" << nt << endl;
5236
cout << "ie=" << ie << " nbe=" << nbe << endl;
5238
ffassert( nv == np );
5239
ffassert( ie ==nbe);
5240
ffassert( itt == nt );
5244
Mesh3 *Tht = new Mesh3( nv, nt, nbe, v, t, b);
5245
Tht->BuildGTree(); // Add JM. Oct 2010
5302
AnyType Op_trunc_mesh3::Op::operator()(Stack stack) const {
5253
AnyType Op_trunc_mesh3::Op::operator()(Stack stack) const {
5304
5255
Mesh3 *pTh = GetAny<Mesh3 *>((*getmesh)(stack));
5305
5256
Mesh3 &Th = *pTh;