From 5f86cea7fa4fe337a74c47b41ea2b36ed49965a8 Mon Sep 17 00:00:00 2001 From: Bastien Gorissen <bastien.gorissen@cenaero.be> Date: Fri, 2 Apr 2010 09:22:47 +0000 Subject: [PATCH] --- Geo/MVertex.h | 2 +- Mesh/HighOrder.cpp | 8 +- Mesh/HighOrder.h | 3 +- Mesh/highOrderSmoother.cpp | 205 +++++++++++++++++++++++++++---------- Mesh/highOrderSmoother.h | 1 + Solver/dofManager.h | 6 +- Solver/femTerm.h | 4 +- Solver/linearSystemFull.h | 3 + 8 files changed, 167 insertions(+), 65 deletions(-) diff --git a/Geo/MVertex.h b/Geo/MVertex.h index 7109913569..b817b8bb68 100644 --- a/Geo/MVertex.h +++ b/Geo/MVertex.h @@ -76,7 +76,7 @@ class MVertex{ inline GEntity* onWhat() const { return _ge; } inline void setEntity(GEntity *ge) { _ge = ge; } - // get the immutable vertex number + // get the immutab vertex number inline int getNum() const { return _num; } // force the immutable number (this should normally never be used) diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp index c1af7e7db6..bdae7c5046 100644 --- a/Mesh/HighOrder.cpp +++ b/Mesh/HighOrder.cpp @@ -925,7 +925,7 @@ void SetOrder1(GModel *m) removeHighOrderVertices(*it); } -static void checkHighOrderTriangles(const char* cc, GModel *m, +void checkHighOrderTriangles(const char* cc, GModel *m, std::vector<MElement*> &bad, double &minJGlob) { bad.clear(); @@ -960,7 +960,7 @@ static void checkHighOrderTriangles(const char* cc, GModel *m, if (minJGlob > 0) Msg::Info("%s : Worst Face Smoothness %g Gamma %g NbFair = %d", cc, minJGlob, minGGlob,nbfair ); - else + else Msg::Warning("%s : Worst Face Smoothness %g (%d negative jacobians) " "Worst Gamma %g Avg Smoothness %g", cc, minJGlob, bad.size(), minGGlob, avg / (count ? count : 1)); @@ -987,10 +987,10 @@ static void checkHighOrderTetrahedron(const char* cc, GModel *m, else if (disto < 0.2) nbfair++; } } - if (minJGlob > 0) + if (minJGlob < 0) Msg::Info("%s : Worst Tetrahedron Smoothness %g Gamma %g NbFair = %d", cc, minJGlob, minGGlob, nbfair); - else + else Msg::Warning("%s : Worst Tetrahedron Smoothness %g (%d negative jacobians) " "Worst Gamma %g Avg Smoothness %g", cc, minJGlob, bad.size(), minGGlob, avg / (count ? count : 1)); diff --git a/Mesh/HighOrder.h b/Mesh/HighOrder.h index 075bb2b372..c8f10b9462 100644 --- a/Mesh/HighOrder.h +++ b/Mesh/HighOrder.h @@ -33,5 +33,6 @@ MTriangle* setHighOrder(MTriangle *t, int nPts = 1, highOrderSmoother *displ2D = 0, highOrderSmoother *displ3D = 0); - +void checkHighOrderTriangles(const char* cc, GModel *m, + std::vector<MElement*> &bad, double &minJGlob); #endif diff --git a/Mesh/highOrderSmoother.cpp b/Mesh/highOrderSmoother.cpp index a1cb1f5da3..cf41201773 100644 --- a/Mesh/highOrderSmoother.cpp +++ b/Mesh/highOrderSmoother.cpp @@ -352,12 +352,20 @@ void highOrderSmoother::smooth(GRegion *gr) // of an element that correspond to the deformation of a straight // sided element to a curvilinear one + + + void highOrderSmoother::optimize(GFace * gf, edgeContainer &edgeVertices, faceContainer &faceVertices) { // if (gf->geomType() != GEntity::Plane) return; + std::vector<MElement*> bad; + double worst; + int count = 0; + + while (1) { // relocate the vertices using elliptic smoother // smooth(gf); @@ -368,11 +376,14 @@ void highOrderSmoother::optimize(GFace * gf, // then try to swap for better configurations smooth(gf, true); + + /* for (int i=0;i<100;i++){ int nbSwap = swapHighOrderTriangles(gf,edgeVertices,faceVertices,this); printf("%d swaps\n",nbSwap); } + */ // smooth(gf,true); // smooth(gf,true); // smooth(gf,true); @@ -573,7 +584,6 @@ double highOrderSmoother::smooth_metric_(std::vector<MElement*> & v, J23K33.gemm(J23, K33, 1, 0); K22.gemm(J23K33, J32, 1, 0); J23K33.mult(D3, R2); - // J23K33.print("J23K33"); for (int j = 0; j < n2; j++){ Dof RDOF = El.getLocalDofR(&se, j); myAssembler.assemble(RDOF, -R2(j)); @@ -751,12 +761,11 @@ void highOrderSmoother::smooth_cavity(std::vector<MElement*>& cavity, for (unsigned int i = 0; i < layer.size(); i++){ if (find(old_elems.begin(), old_elems.end(), layer[i]) == old_elems.end()) { - // printf("In the layer, there is element %d\n", layer[i]->getNum()); for (int j = 0; j < layer[i]->getNumVertices(); j++){ - MVertex *vert = layer[i]->getVertex(j); - myAssembler.fixVertex(vert, 0, getTag(), 0); - myAssembler.fixVertex(vert, 1, getTag(), 0); - // printf("Fixing vertex (internal) %d\n", vert->getNum()); + MVertex *vert = layer[i]->getVertex(j); + myAssembler.fixVertex(vert, 0, getTag(), 0); + myAssembler.fixVertex(vert, 1, getTag(), 0); + //printf("Fixing vertex %d\n", vert->getNum()); } } } @@ -777,7 +786,7 @@ void highOrderSmoother::smooth_cavity(std::vector<MElement*>& cavity, MVertex *vert = cavity[i]->getVertex(j); its = _straightSidedLocation.find(vert); if (its == _straightSidedLocation.end()) { - // printf("SETTING LOCATIONS for %d\n",vert->getNum()); + //printf("SETTING LOCATIONS for %d\n",vert->getNum()); _straightSidedLocation[vert] = SVector3(vert->x(), vert->y(), vert->z()); _targetLocation[vert] = @@ -789,7 +798,7 @@ void highOrderSmoother::smooth_cavity(std::vector<MElement*>& cavity, if (vert->onWhat()->dim() < _dim){ myAssembler.fixVertex(vert, 0, getTag(), 0); myAssembler.fixVertex(vert, 1, getTag(), 0); - // printf("Fixing vertex (boundary) %d\n", vert->getNum()); + //printf("Fixing vertex %d\n", vert->getNum()); } } } @@ -799,23 +808,23 @@ void highOrderSmoother::smooth_cavity(std::vector<MElement*>& cavity, for (unsigned int i = 0; i < cavity.size(); i++){ for (int j = 0; j < cavity[i]->getNumVertices(); j++){ MVertex *vert = cavity[i]->getVertex(j); - // printf("Numbering vertex %d\n",vert->getNum()); + //printf("Numbering vertex %d\n",vert->getNum()); myAssembler.numberVertex(vert, 0, getTag()); myAssembler.numberVertex(vert, 1, getTag()); verticesToMove.insert(vert); } } - // Msg::Info("%d vertices FIXED %d NUMBERED\n", myAssembler.sizeOfF() - // , myAssembler.sizeOfR()); - + //Msg::Info("%d vertices FIXED %d NUMBERED\n", myAssembler.sizeOfF() + // , myAssembler.sizeOfR()); + double dx0 = smooth_metric_(cavity, gf, myAssembler, verticesToMove, El); double dx = dx0; - // printf(" dx0 = %12.5E\n", dx0); + //printf(" dx0 = %12.5E\n", dx0); int iter = 0; while(1){ double dx2 = smooth_metric_(cavity, gf, myAssembler, verticesToMove, El); - // printf(" dx2 = %12.5E\n", dx2); + //printf(" dx2 = %12.5E\n", dx2); if (fabs(dx2 - dx) < 1.e-4 * dx0)break; if (iter++ > 2)break; dx = dx2; @@ -837,7 +846,7 @@ void highOrderSmoother::smooth_cavity(std::vector<MElement*>& cavity, (*it)->y() = p.y(); (*it)->z() = p.z(); } - // printf(" Moving %d to %g %g %g\n", (*it)->getNum(),_targetLocation[(*it)][0], _targetLocation[(*it)][1],_targetLocation[(*it)][2] ); + //printf(" Moving %d to %g %g %g\n", (*it)->getNum(),_targetLocation[(*it)][0], _targetLocation[(*it)][1],_targetLocation[(*it)][2] ); } /* @@ -848,7 +857,7 @@ void highOrderSmoother::smooth_cavity(std::vector<MElement*>& cavity, } lsys->systemSolve(); -} + } for (it = verticesToMove.begin(); it != verticesToMove.end(); ++it){ it->first->x() += myAssembler.getDofValue(it->first, 0, getTag()); it->first->y() += myAssembler.getDofValue(it->first, 1, getTag()); @@ -1136,13 +1145,13 @@ struct swap_triangles_pN !t1->getNumFaceVertices(), t1->getPolynomialOrder()-1,s); - //optimalLocationPN_ (gf,me, t3, t4,s); + optimalLocationPN_ (gf,me, t3, t4,s); std::vector<MElement*> cavity, old_elems; cavity.push_back(t3); cavity.push_back(t4); old_elems.push_back(t1); old_elems.push_back(t2); - s->smooth_cavity(cavity, old_elems, gf); + //s->smooth_cavity(cavity, old_elems, gf); const double qnew1 = shapeMeasure(t3); const double qnew2 = shapeMeasure(t4); @@ -1151,7 +1160,7 @@ struct swap_triangles_pN quality_old = std::min(qold1,qold2); // if (quality_old < quality_new) - // printf("QUALITY GOING FROM %12.5E TO %12.5E\n",quality_old,quality_new); + //printf("QUALITY GOING FROM %12.5E TO %12.5E\n",quality_old,quality_new); } bool operator < (const swap_triangles_pN &other) const @@ -1295,6 +1304,10 @@ static int swapHighOrderTriangles(GFace *gf, faceContainer &faceVertices, highOrderSmoother *s) { + printf ("Initial Size of the map %d\n", edgeVertices.size()); + printf ("Initial Size of the face map %d\n", faceVertices.size()); + + e2t_cont adj; buildEdgeToTriangle(gf->triangles, adj); @@ -1308,7 +1321,7 @@ static int swapHighOrderTriangles(GFace *gf, const double qold1 = shapeMeasure(t1); const double qold2 = shapeMeasure(t2); - if (qold1 < 0.005 || qold2 < 0.005) + //if (qold1 < 0.6 || qold2 < 0.06) pairs.insert(swap_triangles_pN(it->first,t1,t2,gf, edgeVertices,faceVertices,s)); } @@ -1348,24 +1361,66 @@ static int swapHighOrderTriangles(GFace *gf, std::vector<MVertex*> vf3(v3.begin()+3*o3,v3.end()); std::vector<MVertex*> vf4(v4.begin()+3*o4,v4.end()); - // printf("========== Diff = %g\n",diff); - bool t1_rem = (t_removed.find(itp->t1) != t_removed.end()); bool t2_rem = (t_removed.find(itp->t2) != t_removed.end()); - // if ( t1_rem) - // printf("====== Eww, t1 is going DOWN!\n"); - - // if ( t2_rem) - // printf("====== Eww, t2 is going DOWN!\n"); - - if ( !t1_rem && !t2_rem && - //itp->quality_new > itp->quality_old && + itp->quality_new > 0 && //itp->quality_old && diff < 1.e-9){ - // printf("Element quality : %f --> %f\n",itp->quality_old,itp->quality_new); - + //printf("Element quality : %f --> %f\n",itp->quality_old,itp->quality_new); + + // determining the common edge between t1 & t2 + MVertex* common_vertices[2]; + int this_one = 0; + for (std::vector<MVertex*>::iterator t1it = v1.begin(); t1it != v1.begin()+3; t1it++) + for (std::vector<MVertex*>::iterator t2it = v2.begin(); t2it != v2.begin()+3; t2it++) + if ((MVertex*)(*t1it) == (MVertex*)(*t2it)) { + common_vertices[this_one] = (MVertex*)(*t1it); + this_one++; + break; + } + + + for (edgeContainer::iterator ecit = edgeVertices.begin(); ecit != edgeVertices.end(); ecit++) { + if (((*ecit).first.first == common_vertices[0] && + (*ecit).first.second == common_vertices[1]) || + ((*ecit).first.first == common_vertices[1] && + (*ecit).first.second == common_vertices[0])) { + //printf ("Hehe, gotcha !\n"); + edgeVertices.erase(ecit); + } + } + /* + for (faceContainer::iterator fcit = faceVertices.begin(); fcit != faceVertices.end(); fcit++) { + bool remove_this = true; + for (std::vector<MVertex*>::iterator t1it = v1.begin(); t1it != v1.begin()+3; t1it++) { + if (find((*fcit).second.begin(), (*fcit).second.end(), (*t1it)) == (*fcit).second.end()) { + remove_this = false; + break; + } + } + if (remove_this) { + faceVertices.erase(fcit); + printf("Yeah, you're dead.\n"); + break; + } + + remove_this = true; + + for (std::vector<MVertex*>::iterator t2it = v2.begin(); t2it != v2.begin()+3; t2it++) { + if (find((*fcit).second.begin(), (*fcit).second.end(), (*t2it)) == (*fcit).second.end()) { + remove_this = false; + break; + } + } + if (remove_this) { + faceVertices.erase(fcit); + printf("Huh-uh, you too are destroyed.\n"); + break; + } + } +*/ t_removed.insert(itp->t1); t_removed.insert(itp->t2); v_removed.insert(vf1.begin(),vf1.end()); @@ -1380,25 +1435,73 @@ static int swapHighOrderTriangles(GFace *gf, if (find(ve2.begin(),ve2.end(),*vit)!=ve2.end()) v_removed.insert(*vit); } - for(std::vector<MVertex*>::iterator vit = ve3.begin(); vit != ve3.end(); vit++) { + //for(std::vector<MVertex*>::iterator vit = ve3.begin(); vit != ve3.end(); vit++) { //if (find(ve4.begin(),ve4.end(),*vit)!=ve4.end()) // mesh_vertices2.push_back(*vit); - } + //} nbSwap++; } else { - if (!t1_rem || !t2_rem) { - for(std::vector<MVertex*>::iterator vit = ve1.begin(); vit != ve1.end(); vit++) { - //if (find(ve2.begin(),ve2.end(),*vit)!=ve2.end()) - //mesh_vertices2.push_back(*vit); - } - } - for(std::vector<MVertex*>::iterator vit = ve3.begin(); vit != ve3.end(); vit++) { if (find(ve4.begin(),ve4.end(),*vit)!=ve4.end()) v_removed.insert(*vit); + //delete *vit; } + + // determining the common edge between t3 & t4 + MVertex* common_vertices[2]; + int this_one = 0; + for (std::vector<MVertex*>::iterator t3it = v3.begin(); t3it != v3.begin()+3; t3it++) + for (std::vector<MVertex*>::iterator t4it = v4.begin(); t4it != v4.begin()+3; t4it++) + if ((MVertex*)(*t3it) == (MVertex*)(*t4it)) { + common_vertices[this_one] = (MVertex*)(*t3it); + this_one++; + break; + } + + + for (edgeContainer::iterator ecit = edgeVertices.begin(); ecit != edgeVertices.end(); ecit++) { + if (((*ecit).first.first == common_vertices[0] && + (*ecit).first.second == common_vertices[1]) || + ((*ecit).first.first == common_vertices[1] && + (*ecit).first.second == common_vertices[0])) { + //printf ("Hehe, gotcha !\n"); + edgeVertices.erase(ecit); + } + } + + /* + for (faceContainer::iterator fcit = faceVertices.begin(); fcit != faceVertices.end(); fcit++) { + bool remove_this = true; + for (std::vector<MVertex*>::iterator t3it = v3.begin(); t3it != v3.begin()+3; t3it++) { + if (find((*fcit).second.begin(), (*fcit).second.end(), (*t3it)) == (*fcit).second.end()) { + remove_this = false; + break; + } + } + if (remove_this) { + faceVertices.erase(fcit); + printf("Yeah, you're dead.\n"); + break; + } + + remove_this = true; + + for (std::vector<MVertex*>::iterator t4it = v4.begin(); t4it != v4.begin()+3; t4it++) { + if (find((*fcit).second.begin(), (*fcit).second.end(), (*t4it)) == (*fcit).second.end()) { + remove_this = false; + break; + } + } + if (remove_this) { + faceVertices.erase(fcit); + printf("Huh-uh, you too are destroyed.\n"); + break; + } + } + */ + delete itp->t3; delete itp->t4; } @@ -1408,20 +1511,13 @@ static int swapHighOrderTriangles(GFace *gf, for (unsigned int i = 0; i < gf->mesh_vertices.size(); i++){ if (v_removed.find(gf->mesh_vertices[i]) == v_removed.end()){ mesh_vertices2.push_back(gf->mesh_vertices[i]); - c1++; - } - else { - //mesh_vertices2.push_back(gf->mesh_vertices[i]); + } //else { //delete gf->mesh_vertices[i]; - c2++; - } + //} } - Msg::Info("Deleted %d (%d) vertices from %d", c2, - (int)v_removed.size(), (int)gf->mesh_vertices.size()); + gf->mesh_vertices.clear(); gf->mesh_vertices = mesh_vertices2; - Msg::Info("Deleted %d vertices from %d", c2, (int)gf->mesh_vertices.size()); - Msg::Info("Added %d vertices",c1); for (unsigned int i = 0; i < gf->triangles.size(); i++){ if (t_removed.find(gf->triangles[i]) == t_removed.end()){ @@ -1431,10 +1527,11 @@ static int swapHighOrderTriangles(GFace *gf, delete gf->triangles[i]; } } - - Msg::Info("replacing triangles %d by %d", (int)gf->triangles.size(), - (int)triangles2.size()); + gf->triangles.clear(); gf->triangles = triangles2; + printf("%d swaps performed\n",nbSwap); + printf ("Size of the map d%\n", edgeVertices.size()); + printf ("Size of the face map %d\n", faceVertices.size()); return nbSwap; } diff --git a/Mesh/highOrderSmoother.h b/Mesh/highOrderSmoother.h index 766613cf5e..15d7737414 100644 --- a/Mesh/highOrderSmoother.h +++ b/Mesh/highOrderSmoother.h @@ -59,6 +59,7 @@ public: void swap(GFace *, edgeContainer &edgeVertices, faceContainer &faceVertices); + void optimize(GFace *, edgeContainer &edgeVertices, faceContainer &faceVertices); diff --git a/Solver/dofManager.h b/Solver/dofManager.h index b966904ddd..49fa8f527d 100644 --- a/Solver/dofManager.h +++ b/Solver/dofManager.h @@ -85,7 +85,7 @@ class dofManager{ // fixations on full blocks, treated by eliminating equations: // DofVec = dataVec - std::map<Dof, dataVec> fixed; + std::map<Dof, dataVec> fixed ; // initial conditions std::map<Dof, std::vector<dataVec> > initial; @@ -118,7 +118,7 @@ class dofManager{ inline void fixVertex(MVertex*v, int iComp, int iField, const dataVec &value) { fixDof(v->getNum(), Dof::createTypeWithTwoInts(iComp, iField), value); - } + } inline void numberDof(Dof key) { if(fixed.find(key) != fixed.end()) return; @@ -162,7 +162,7 @@ class dofManager{ inline dataVec getDofValue(int ent, int type) const { Dof key(ent, type); - { + { typename std::map<Dof, dataVec>::const_iterator it = fixed.find(key); if (it != fixed.end()) return it->second; } diff --git a/Solver/femTerm.h b/Solver/femTerm.h index 4478016e01..849c949fe3 100644 --- a/Solver/femTerm.h +++ b/Solver/femTerm.h @@ -81,11 +81,11 @@ class femTerm { std::vector<Dof> R,C; // better use default consdtructors and reserve the right amount of space to avoid reallocation R.reserve(nbR); C.reserve(nbC); - bool sym=true; + bool sym=true; if (nbR == nbC) { for (int j = 0; j < nbR; j++) - { + { Dof r(getLocalDofR(se, j)); Dof c(getLocalDofC(se, j)); R.push_back(r); diff --git a/Solver/linearSystemFull.h b/Solver/linearSystemFull.h index 01c6b939fc..ca0fe74a61 100644 --- a/Solver/linearSystemFull.h +++ b/Solver/linearSystemFull.h @@ -72,6 +72,9 @@ class linearSystemFull : public linearSystem<scalar> { } virtual int systemSolve() { + _a->print("A in solve"); + _b->print("B in solve"); + _x->print("X in solve"); if (_b->size()) _a->luSolve(*_b, *_x); return 1; -- GitLab