diff --git a/Mesh/delaunay3d.cpp b/Mesh/delaunay3d.cpp index c97434a7456f85be18ae4c3a3784b48886d9f250..dea924898fe661474f67b61ae61b5fd7a35f6194 100644 --- a/Mesh/delaunay3d.cpp +++ b/Mesh/delaunay3d.cpp @@ -30,6 +30,9 @@ const int MEASURE_BARR = 0; #include <numa.h> #endif +int Tet::in_sphere_counter = 0; + + struct HilbertSortB { // The code for generating table transgc @@ -333,9 +336,8 @@ static void delaunayCavity2 (Tet *t, else if (neigh == prev){ } else if (!neigh->inSphere(v,thread)){ - Face f = t->getFace(iNeigh); - bnd.push_back(conn(f,iNeigh,neigh)); - // neigh->set(thread, iPnt); + bnd.push_back(conn(t->getFace(iNeigh),iNeigh,neigh)); + neigh->set(thread, iPnt); } else if (!(neigh->isSet(thread, iPnt))) { delaunayCavity2 (neigh, t, v, cavity,bnd,thread, iPnt); @@ -399,7 +401,6 @@ Tet* walk (Tet *t, Vertex *v, int maxx, double &totSearch, int thread){ } - void __print (const char *name, connContainer &conn){ FILE *f = fopen(name,"w"); fprintf(f,"View \"\"{\n"); @@ -517,7 +518,7 @@ static Tet* randomTet (int thread, tetContainer &allocator ){ } -#define _VERBOSE 1 +//#define _VERBOSE 1 void delaunayTrgl (const unsigned int numThreads, const unsigned int NPTS_AT_ONCE, unsigned int Npts, @@ -528,6 +529,8 @@ void delaunayTrgl (const unsigned int numThreads, double totCavityGlob=0; #endif + double t1,t2=0,t3=0,t4=0; + // checkLocalDelaunayness(allocator, 0, "initial"); std::vector<int> invalidCavities(numThreads); @@ -588,6 +591,7 @@ void delaunayTrgl (const unsigned int numThreads, std::vector<Tet*> t(NPTS_AT_ONCE); // double c1 = Cpu(); // FIND SEEDS + t1 = Cpu(); for (unsigned int K=0; K< NPTS_AT_ONCE; K++) { vToAdd[K] = iPGlob < locSizeK[K] ? &allocatedVerts[K][iPGlob] : NULL; if(vToAdd[K]){ @@ -602,24 +606,24 @@ void delaunayTrgl (const unsigned int numThreads, } } } + t2+= Cpu() - t1; // double c1 = Cpu(); // BUILD CAVITIES + t1 = Cpu(); for (unsigned int K=0; K< NPTS_AT_ONCE; K++) { if(vToAdd[K]){ cavityContainer &cavityK = cavity[K]; connContainer &bndK = bnd[K]; for (unsigned int i=0; i<cavityK.size(); i++)cavityK[i]->unset(myThread,K); - // for (unsigned int i=0; i< bndK.size(); i++)if(bndK[i].t)bndK[i].t->unset(myThread,K); + for (unsigned int i=0; i<bndK.size(); i++)if(bndK[i].t)bndK[i].t->unset(myThread,K); cavityK.clear(); bndK.clear(); - delaunayCavity(t[K], NULL, vToAdd[K], cavityK, bndK, myThread, K); - for (unsigned int i=0; i<cavityK.size(); i++)cavityK[i]->unset(myThread,K); - // for (unsigned int i=0; i< bndK.size(); i++)if(bndK[i].t)bndK[i].t->unset(myThread,K); + delaunayCavity2(t[K], NULL, vToAdd[K], cavityK, bndK, myThread, K); // verify the cavity for (unsigned int i=0; i< bndK.size(); i++) { - double val = robustPredicates::orient3d((double*)bndK[i].f.V[0], - (double*)bndK[i].f.V[1], - (double*)bndK[i].f.V[2], - (double*)vToAdd[K]); + const double val = robustPredicates::orient3d((double*)bndK[i].f.V[0], + (double*)bndK[i].f.V[1], + (double*)bndK[i].f.V[2], + (double*)vToAdd[K]); if (val <= 0 ) { vToAdd[K] = NULL; invalidCavities [myThread]++; @@ -629,6 +633,7 @@ void delaunayTrgl (const unsigned int numThreads, } } + t3 += Cpu() - t1; #pragma omp barrier @@ -636,7 +641,8 @@ void delaunayTrgl (const unsigned int numThreads, if (!vToAdd[K])ok[K]=false; else ok[K] = canWeProcessCavity (cavity[K], myThread, K); } - + t1 = Cpu(); + for (unsigned int K=0; K< NPTS_AT_ONCE; K++) { if (ok[K]){ cavityContainer &cavityK = cavity[K]; @@ -670,6 +676,7 @@ void delaunayTrgl (const unsigned int numThreads, } } } + t4 += Cpu() - t1; } #ifdef _VERBOSE #pragma omp critical @@ -679,6 +686,11 @@ void delaunayTrgl (const unsigned int numThreads, } #endif #pragma omp barrier + // clear last cavity + for (unsigned int K=0; K< NPTS_AT_ONCE; K++) { + for (unsigned int i=0; i<cavity[K].size(); i++)cavity[K][i]->unset(myThread,K); + for (unsigned int i=0; i<bnd[K].size(); i++)if(bnd[K][i].t)bnd[K][i].t->unset(myThread,K); + } } if (invalidCavities[0])Msg::Warning("%d invalid cavities",invalidCavities[0]); @@ -686,12 +698,14 @@ void delaunayTrgl (const unsigned int numThreads, //checkLocalDelaunayness(T,"final"); + printf(" %12.5E %12.5E %12.5E tot %12.5E \n",t2,t3,t4,t2+t3+t4); + #ifdef _VERBOSE printf("average searches per point %12.5E\n",totSearchGlob/Npts); printf("average size for del cavity %12.5E\n",totCavityGlob/Npts); - printf("cash misses: "); - for (int i=0;i<numThreads;i++){ - printf("%4d ",(int)cacheMisses[i]); + printf("cache misses: "); + for (unsigned int i=0;i<numThreads;i++){ + printf("%4ud ",(int)cacheMisses[i]); } printf("\n"); @@ -815,6 +829,8 @@ void delaunayTriangulation (const int numThreads, } double d = 1*sqrt ( maxx*maxx + maxy*maxy + maxz*maxz ); + tetContainer allocator (1, S.size() * 10); + for (unsigned int i=0;i<N;i++){ MVertex *mv = S[i]; // FIXME : should be zero !!!! @@ -824,6 +840,7 @@ void delaunayTriangulation (const int numThreads, mv->x() += dx; mv->y() += dy; mv->z() += dz; + // Vertex *v = new Vertex (mv->x(),mv->y(),mv->z(),1.e22,i+1); Vertex *v = new Vertex (mv->x(),mv->y(),mv->z(),1.e22,i+1); _vertices.push_back(v); _temp [v->getNum()] = mv; @@ -832,7 +849,7 @@ void delaunayTriangulation (const int numThreads, robustPredicates::exactinit(1,maxx,maxy,maxz); // FIXME numThreads - tetContainer allocator (1, S.size() * 10); + Vertex *box[8]; delaunayTriangulation (numThreads, nptsatonce, _vertices, box, allocator); diff --git a/Mesh/delaunay3d_private.h b/Mesh/delaunay3d_private.h index f1a38f2a54520641ab8651a3b5c1e87d8da23e68..def190ba3e0a872a298663d2f74b86047acb7149 100644 --- a/Mesh/delaunay3d_private.h +++ b/Mesh/delaunay3d_private.h @@ -36,7 +36,7 @@ public : inline double &z() {return _x[2];} inline double &lc() {return _lc;} inline operator double *() { return _x; } - Vertex (double X, double Y, double Z, double lc, int num = 0) : _num(num), _thread(0){ + Vertex (double X=0, double Y=0, double Z=0, double lc=0, int num = 0) : _num(num), _thread(0){ _x[0]=X; _x[1]=Y;_x[2]=Z; _lc = lc;} Vertex operator + (const Vertex &other){ return Vertex (x()+other.x(),y()+other.y(),z()+other.z(),other.lc() + _lc); @@ -68,7 +68,7 @@ inline double orientationTestFast(double *pa, double *pb, double *pc, double *pd inline bool inSphereTest_s (Vertex *va, Vertex *vb, Vertex *vc, Vertex *vd , Vertex *ve){ double val = robustPredicates::insphere ((double*)va,(double*)vb,(double*)vc,(double*)vd,(double*)ve); if (val == 0.0){ - Msg::Debug("symbolic perturbation needed vol %22.15E",orientationTestFast((double*)va,(double*)vb,(double*)vc,(double*)vd)); + Msg::Info("symbolic perturbation needed vol %22.15E",orientationTestFast((double*)va,(double*)vb,(double*)vc,(double*)vd)); int count; // symbolic perturbation Vertex *pt[5] = {va,vb,vc,vd,ve}; @@ -160,7 +160,8 @@ struct Tet { Tet *T[4]; Vertex *V[4]; CHECKTYPE _bitset [MAX_NUM_THREADS_]; - char _modified; + bool _modified; + static int in_sphere_counter; Tet () : _modified(true){ V[0] = V[1] = V[2] = V[3] = NULL; T[0] = T[1] = T[2] = T[3] = NULL; @@ -169,6 +170,7 @@ struct Tet { int setVerticesNoTest (Vertex *v0, Vertex *v1, Vertex *v2, Vertex *v3){ _modified=true; V[0] = v0; V[1] = v1; V[2] = v2; V[3] = v3; + // for (int i=0;i<4;i++)_copy[i] = *V[i]; return 1; } int setVertices (Vertex *v0, Vertex *v1, Vertex *v2, Vertex *v3){ @@ -176,11 +178,13 @@ struct Tet { double val = robustPredicates::orient3d((double*)v0,(double*)v1,(double*)v2,(double*)v3); V[0] = v0; V[1] = v1; V[2] = v2; V[3] = v3; if (val > 0){ + // for (int i=0;i<4;i++)_copy[i] = *V[i]; return 1; } else if (val < 0){ // throw; V[0] = v1; V[1] = v0; V[2] = v2; V[3] = v3; + // for (int i=0;i<4;i++)_copy[i] = *V[i]; return -1; } else { @@ -220,13 +224,10 @@ struct Tet { return Edge (std::min(V[edg[k][0]],V[edg[k][1]]), std::max(V[edg[k][0]],V[edg[k][1]])); } - inline bool inSphere (Vertex *vd, int thread) const{ + inline bool inSphere (Vertex *vd, int thread) { + in_sphere_counter++; return inSphereTest_s (V[0],V[1],V[2],V[3],vd); } - Vertex centroid () const { - return (*V[0]+*V[1]+*V[2]+*V[3])*0.25; - } - }; struct conn { @@ -246,32 +247,32 @@ struct conn { // tetrahedra (one per thread) -struct aBunchOfTets { - std::vector<Tet*> _all; +template <class T> class aBunchOfStuff { +public: + std::vector<T*> _all; unsigned int _current; unsigned int _nbAlloc; unsigned int size () { return _current + (_all.size()-1) * _nbAlloc; } - Tet* operator () (unsigned int i){ + T* operator () (unsigned int i){ unsigned int _array = i / _nbAlloc; unsigned int _offset = i % _nbAlloc; // printf("%d %d %d\n",i,_array,_offset); return _all [_array] + _offset; } - aBunchOfTets (unsigned int s) : _current(0), _nbAlloc (s) { - _all.push_back(new Tet [_nbAlloc]); + aBunchOfStuff (unsigned int s) : _current(0), _nbAlloc (s) { + _all.push_back(new T [_nbAlloc]); } - ~aBunchOfTets(){ + ~aBunchOfStuff(){ for (unsigned int i=0;i<_all.size();i++){ delete [] _all[i]; } } - Tet* newTet() { - + T* newStuff() { if (_current == _nbAlloc){ - _all.push_back(new Tet [_nbAlloc]); - printf("REALLOCATION %d\n",_all.size()); + _all.push_back(new T [_nbAlloc]); + // printf("REALLOCATION %d\n",_all.size()); _current = 0; } _current++; @@ -281,21 +282,37 @@ struct aBunchOfTets { // tetAllocator owns the tets that have been allocated by itself class tetContainer { - std::vector<aBunchOfTets*> _perThread; -public: + // std::vector<aBunchOfStuff<Vertex> *> _perThreadV; + std::vector<aBunchOfStuff<Tet> *> _perThread; + public: unsigned int size(int thread) const {return _perThread[thread]->size();} - Tet * operator () (int thread, int j) const {return (*_perThread[thread]) (j);} + // unsigned int sizeV(int thread) const {return _perThreadV[thread]->size();} + inline Tet * operator () (int thread, int j) const {return (*_perThread[thread]) (j);} + // Vertex * getVertex(int thread, int j) const {return (*_perThreadV[thread]) (j);} tetContainer (int nbThreads, int preallocSizePerThread) { // FIXME !!! if (nbThreads != 1) throw; - _perThread.push_back(new aBunchOfTets (preallocSizePerThread) ); - } - Tet * newTet(int thread) { - return _perThread[thread]->newTet(); - } + _perThread.push_back (new aBunchOfStuff<Tet> (preallocSizePerThread) ); + // _perThreadV.push_back(new aBunchOfStuff<Vertex> (preallocSizePerThread) ); + } + inline Tet * newTet(int thread) { + return _perThread[thread]->newStuff(); + } + /* + Vertex * newVertex(int thread, double x, double y, double z, double lc, int num) { + Vertex *v = _perThreadV[thread]->newStuff(); + v->x() = x; + v->y() = y; + v->z() = z; + v->lc() = lc; + v->setNum(num); + return v; + } + */ ~tetContainer(){ // FIXME !!! - delete _perThread[0]; + delete _perThread [0]; + // delete _perThreadV[0]; } }; diff --git a/Mesh/delaunay_refinement.cpp b/Mesh/delaunay_refinement.cpp index 0628eb7745225cd9d9efc4408b69316e33b43d27..7f7fedf6641ed2052332cbb760b499f9507fcf03 100644 --- a/Mesh/delaunay_refinement.cpp +++ b/Mesh/delaunay_refinement.cpp @@ -327,6 +327,16 @@ void edgeBasedRefinement (const int numThreads, } } + + FILE *f = fopen ("pts_init.dat","w"); + fprintf(f,"%d\n",all.size()); + for (std::set<MVertex*>::iterator it = all.begin();it !=all.end(); ++it){ + MVertex *mv = *it; + fprintf(f,"%12.5E %12.5E %12.5E\n",mv->x(),mv->y(),mv->z()); + } + fclose(f); + + _vertices.resize(all.size()); int counter=0; for (std::set<MVertex*>::iterator it = all.begin();it !=all.end(); ++it){ @@ -393,6 +403,7 @@ void edgeBasedRefinement (const int numThreads, Msg::Info("----------------------------------- SATUR FILTR SORTH DELNY TIME TETS"); double __t__ = Cpu(); + Tet::in_sphere_counter = 0; while(1){ std::vector<Vertex*> add; double t1 = Cpu(); @@ -408,8 +419,16 @@ void edgeBasedRefinement (const int numThreads, SortHilbert(add, indices); double t4 = Cpu(); delaunayTrgl (1,1,add.size(), &add,allocator); - add_all.insert (add_all.end(), add.begin(), add.end()); double t5 = Cpu(); + add_all.insert (add_all.end(), add.begin(), add.end()); + // if (iter == 1){ + // FILE *f = fopen ("pts.dat","w"); + // fprintf(f,"%d\n",add.size()); + // for (unsigned int i=0;i<add.size();i++){ + // fprintf(f,"%12.5E %12.5E %12.5E\n",add[i]->x(),add[i]->y(),add[i]->z()); + // } + // fclose(f); + // } Msg::Info("IT %3d %6d points added, timings %5.2f %5.2f %5.2f %5.2f %5.2f %5d",iter,add.size(), (t2-t1), (t3-t2), @@ -417,10 +436,13 @@ void edgeBasedRefinement (const int numThreads, (t5-t4), (t5-__t__), allocator.size(0)); + printf("%d calls to inSphere\n",Tet::in_sphere_counter); iter++; } } + + for (unsigned int i=0; i< allocator.size(0);i++){ Tet *tt = allocator (0,i); MVertex *mvs[4]; diff --git a/Numeric/robustPredicates.cpp b/Numeric/robustPredicates.cpp index e2441a484b033174a313f3f0692aabd61a429d05..846c3a60b1ddb42eb19e66b8e60bd540103d4c5e 100644 --- a/Numeric/robustPredicates.cpp +++ b/Numeric/robustPredicates.cpp @@ -2353,7 +2353,7 @@ REAL orient3d(REAL *pa, REAL *pb, REAL *pc, REAL *pd) if (det < -o3dstaticfilter) return det; } - + permanent = (Absolute(bdxcdy) + Absolute(cdxbdy)) * Absolute(adz) + (Absolute(cdxady) + Absolute(adxcdy)) * Absolute(bdz) + (Absolute(adxbdy) + Absolute(bdxady)) * Absolute(cdz); @@ -2362,7 +2362,7 @@ REAL orient3d(REAL *pa, REAL *pb, REAL *pc, REAL *pd) return det; } - return orient3dadapt(pa, pb, pc, pd, permanent); + return orient3dadapt(pa, pb, pc, pd, permanent); } #endif // ifdef INEXACT_GEOM_PRED