diff --git a/Mesh/highOrderSmoother.cpp b/Mesh/highOrderSmoother.cpp index 6500b83aabef7ea8569925545fc2aca727772fab..755fdd86a10d7e6ae839b2d60ce73671931c5bcd 100644 --- a/Mesh/highOrderSmoother.cpp +++ b/Mesh/highOrderSmoother.cpp @@ -369,7 +369,7 @@ void highOrderSmoother::optimize(GFace * gf, smooth(gf, true); //int nbSwap = - // swapHighOrderTriangles(gf,edgeVertices,faceVertices,this); + //swapHighOrderTriangles(gf,edgeVertices,faceVertices,this); // smooth(gf,true); // smooth(gf,true); // smooth(gf,true); @@ -443,13 +443,9 @@ void highOrderSmoother::smooth_metric(std::vector<MElement*> & all, GFace *gf) double minD; - getDistordedElements(all, .6, v,minD); - - Msg::Debug("%d elements / %d distorted min Disto = %g", all.size(), v.size(), minD); - if (!v.size()) return; - const int nbLayers = 2; + const int nbLayers = 10; //2, originally :) for (int i = 0; i < nbLayers; i++){ addOneLayer(all, v, layer); v.insert(v.end(), layer.begin(), layer.end()); @@ -570,6 +566,7 @@ 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)); @@ -617,9 +614,9 @@ void highOrderSmoother::smooth(std::vector<MElement*> &all) std::vector<MElement*> layer, v; double minD; - getDistordedElements(all, .5, v, minD); + getDistordedElements(all, 0.5, v, minD); - Msg::Debug("%d elements / %d distorted min Disto = %g\n", + Msg::Info("%d elements / %d distorted min Disto = %g\n", all.size(), v.size(), minD); if (!v.size()) return; @@ -716,68 +713,75 @@ void highOrderSmoother::smooth(std::vector<MElement*> &all) void highOrderSmoother::smooth_cavity(std::vector<MElement*>& cavity, std::vector<MElement*>& old_elems, GFace* gf) { + + printf("Smoothing a cavity...\n"); + printf("Old elems : %d and %d\n", old_elems[0]->getNum(), old_elems[1]->getNum()); + printf("Cavity elems : %d and %d\n", cavity[0]->getNum(), cavity[1]->getNum()); - printf("Smoothing a cavity..."); - - linearSystemFull<double> *lsys = new linearSystemFull<double>; +#ifdef HAVE_TAUCS + linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>; + printf("Using Taucs\n"); +#else + linearSystemCSRGmm<double> *lsys = new linearSystemCSRGmm<double>; + lsys->setNoisy(1); + lsys->setGmres(1); + lsys->setPrec(5.e-8); + printf("Using Gmm\n"); +#endif dofManager<double> myAssembler(lsys); - elasticityTerm El(0,1.0,0.333, getTag()); + elasticityTerm El(0, 1.0, 0.333, getTag()); std::vector<MElement*> layer,v; - v.insert(v.begin(), gf->triangles.begin(),gf->triangles.end()); - v.insert(v.begin(), gf->quadrangles.begin(),gf->quadrangles.end()); + /* Debug only :p */ + //cavity = old_elems; + + v.insert(v.end(), gf->triangles.begin(),gf->triangles.end()); + v.insert(v.end(), gf->quadrangles.begin(),gf->quadrangles.end()); addOneLayer(v,cavity,layer); - + //addOneLayer(v,old_elems,layer); + for (unsigned int i = 0; i < layer.size(); i++){ - bool skip = false; - for (std::vector<MElement*>::iterator itold = old_elems.begin(); - itold != old_elems.end(); - itold++) - if (*itold == layer[i]) { - skip = true; - break; + 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 %d\n", vert->getNum()); } - if (skip) continue; - for (int j = 0; j < layer[i]->getNumVertices(); j++){ - MVertex *vert = layer[i]->getVertex(j); - //printf("i = %d, j = %d \n",i,j); - myAssembler.fixVertex(vert, 0, getTag(), 0); - myAssembler.fixVertex(vert, 1, getTag(), 0); } } + //printf("%d vertices \n", _displ.size()); + + std::set<MVertex*>::iterator it; std::map<MVertex*,SVector3>::iterator its; + std::map<MVertex*,SVector3>::iterator itpresent; + std::map<MVertex*,SVector3>::iterator ittarget; + //std::map<MVertex*,SVector3> verticesToMove; std::set<MVertex*> verticesToMove; 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("Vertex on dim %d with tag %d\n",vert->onWhat()->dim(),vert->onWhat()->tag()); - - // printf("%d %d %d v\n", i, j, v[i]->getNumVertices()); its = _straightSidedLocation.find(vert); - if (its == _straightSidedLocation.end()){ - //printf("Ping\n"); + if (its != _straightSidedLocation.end()) { + printf("SETTING LOCATIONS for %d\n",vert->getNum()); _straightSidedLocation[vert] = SVector3(vert->x(), vert->y(), vert->z()); _targetLocation[vert] = - SVector3(vert->x(), vert->y(), vert->z()); - if (vert->onWhat()->dim() < _dim){ - myAssembler.fixVertex(vert, 0, getTag(), 0); - myAssembler.fixVertex(vert, 1, getTag(), 0); - } - } - else{ - //printf("Pong\n"); - vert->x() = its->second.x(); + SVector3(vert->x(), vert->y(), vert->z()); + }else { + vert->x() = its->second.x(); vert->y() = its->second.y(); vert->z() = its->second.z(); if (vert->onWhat()->dim() < _dim){ myAssembler.fixVertex(vert, 0, getTag(), 0); myAssembler.fixVertex(vert, 1, getTag(), 0); + printf("Fixing vertex %d\n", vert->getNum()); } } } @@ -786,18 +790,16 @@ void highOrderSmoother::smooth_cavity(std::vector<MElement*>& cavity, // number the other DOFs for (unsigned int i = 0; i < cavity.size(); i++){ for (int j = 0; j < cavity[i]->getNumVertices(); j++){ - //printf("Numbering i = %d, j = %d \n",i,j); - //printf("%d vertices FIXED %d NUMBERED\n", myAssembler.sizeOfF() - // , myAssembler.sizeOfR()); MVertex *vert = cavity[i]->getVertex(j); + 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; @@ -811,8 +813,6 @@ void highOrderSmoother::smooth_cavity(std::vector<MElement*>& cavity, dx = dx2; } - std::set<MVertex*>::iterator it; - for (it = verticesToMove.begin(); it != verticesToMove.end(); ++it){ SPoint2 param; reparamMeshVertexOnFace(*it, gf, param); @@ -829,8 +829,24 @@ 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] ); } - + + /* + if (myAssembler.sizeOfR()) { + for (unsigned int i = 0; i < cavity.size(); i++) { + SElement se(cavity[i]); + El.addToMatrix(myAssembler, &se); + } + 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()); + it->first->z() += myAssembler.getDofValue(it->first, 2, getTag()); + } + */ delete lsys; } @@ -1100,10 +1116,10 @@ struct swap_triangles_pN reparamMeshEdgeOnFace(n3,n4,gf,p3,p4); s_before = surfaceTriangleUV(p1,p2,p4) + surfaceTriangleUV(p1,p2,p3); - s_after = surfaceTriangleUV(p3,p4,p1) + surfaceTriangleUV(p3,p4,p2); + s_after = surfaceTriangleUV(p1,p4,p3) + surfaceTriangleUV(p3,p4,p2); - MTriangle t3lin(n3,n4,n1); - MTriangle t4lin(n4,n3,n2); + MTriangle t3lin(n1,n4,n3); + MTriangle t4lin(n3,n4,n2); t3 = setHighOrder(&t3lin,gf,edgeVertices,faceVertices,false, !t1->getNumFaceVertices(), @@ -1111,7 +1127,7 @@ struct swap_triangles_pN t4 = setHighOrder(&t4lin,gf,edgeVertices,faceVertices,false, !t1->getNumFaceVertices(), t1->getPolynomialOrder()-1,s); - + //optimalLocationPN_ (gf,me, t3, t4,s); std::vector<MElement*> cavity, old_elems; cavity.push_back(t3); @@ -1286,11 +1302,12 @@ static int swapHighOrderTriangles(GFace *gf, const double qold1 = shapeMeasure(t1); const double qold2 = shapeMeasure(t2); - if (qold1 < 0.6 || qold2 < 0.6) + if (qold1 < 0.005 || qold2 < 0.005) pairs.insert(swap_triangles_pN(it->first,t1,t2,gf, edgeVertices,faceVertices,s)); } } + std::set<swap_triangles_pN>::iterator itp = pairs.begin(); int nbSwap = 0; @@ -1315,6 +1332,7 @@ static int swapHighOrderTriangles(GFace *gf, itp->t2->getFaceVertices(0,v2); itp->t3->getFaceVertices(0,v3); itp->t4->getFaceVertices(0,v4); + std::vector<MVertex*> ve1(v1.begin()+3,v1.begin()+3*o1); std::vector<MVertex*> ve2(v2.begin()+3,v2.begin()+3*o2); std::vector<MVertex*> ve3(v3.begin()+3,v3.begin()+3*o3); @@ -1324,77 +1342,76 @@ 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()); - // for (int ed = 0; ed < 3; ed++) { - // std::vector<MVertex*> v1,v2,v3,v4; - // itp->t1->getEdgeVertices(ed,v1); - // itp->t2->getEdgeVertices(ed,v2); - // itp->t3->getEdgeVertices(ed,v3); - // itp->t4->getEdgeVertices(ed,v4); - // ve1.insert(ve1.end(),v1.begin()+2,v1.end()); - // ve2.insert(ve2.end(),v2.begin()+2,v2.end()); - // ve3.insert(ve3.end(),v3.begin()+2,v3.end()); - // ve4.insert(ve4.end(),v4.begin()+2,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 ( t_removed.find(itp->t1) == t_removed.end() && - t_removed.find(itp->t2) == t_removed.end() && - itp->quality_new > itp->quality_old && + 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 && diff < 1.e-9){ - // itp->print(); - printf("quality was %f, is now %f\n",itp->quality_old,itp->quality_new); + + printf("Element quality : %f --> %f\n",itp->quality_old,itp->quality_new); + t_removed.insert(itp->t1); t_removed.insert(itp->t2); - triangles2.push_back(itp->t3); - triangles2.push_back(itp->t4); - v_removed.insert(vf1.begin(),vf1.end()); v_removed.insert(vf2.begin(),vf2.end()); + + triangles2.push_back(itp->t3); + triangles2.push_back(itp->t4); mesh_vertices2.insert(mesh_vertices2.end(),vf3.begin(),vf3.end()); mesh_vertices2.insert(mesh_vertices2.end(),vf4.begin(),vf4.end()); for(std::vector<MVertex*>::iterator vit = ve1.begin(); vit != ve1.end(); vit++) { - if (find(ve2.begin(),ve2.begin(),*vit)!=ve2.end()) + 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++) { - if (find(ve4.begin(),ve4.end(),*vit)!=ve4.end()) - mesh_vertices2.push_back(*vit); + //if (find(ve4.begin(),ve4.end(),*vit)!=ve4.end()) + // mesh_vertices2.push_back(*vit); } - // if (itp->n34 != itp->n12){ - // v_removed.insert(itp->n12); - // mesh_vertices2.push_back(itp->n34); - // } nbSwap++; } - else{ - 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); + 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 itp->t3; delete itp->t4; - - // if (itp->n34 != itp->n12) delete itp->n34; } ++itp; } int c1=0,c2=0; 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]); + mesh_vertices2.push_back(gf->mesh_vertices[i]); c1++; } else { - delete gf->mesh_vertices[i]; + //mesh_vertices2.push_back(gf->mesh_vertices[i]); + //delete gf->mesh_vertices[i]; c2++; } } + + printf("Deleted %d (%d) vertices from %d\n",c2,v_removed.size(),gf->mesh_vertices.size()); gf->mesh_vertices = mesh_vertices2; printf("Deleted %d vertices from %d\n", c2, (int)gf->mesh_vertices.size()); printf("Added %d vertices\n",c1); @@ -1408,7 +1425,7 @@ static int swapHighOrderTriangles(GFace *gf, } } - printf("replacing %d by %d\n", (int)gf->triangles.size(), (int)triangles2.size()); + printf("replacing triangles %d by %d\n",gf->triangles.size(),triangles2.size()); gf->triangles = triangles2; return nbSwap; } diff --git a/Mesh/qualityMeasures.cpp b/Mesh/qualityMeasures.cpp index b40307e9f0f5e7de3f8a61d5b2d9d6df16508554..703320d751e97b0f2e9e4c9ebe0a2ba189638aac 100644 --- a/Mesh/qualityMeasures.cpp +++ b/Mesh/qualityMeasures.cpp @@ -327,11 +327,11 @@ double qmDistorsionOfMapping(MTetrahedron *e) } double qmTriangleAngles (MTriangle *e) { - double a = 100; + double a = 500; double worst_quality = std::numeric_limits<double>::max(); double mat[3][3]; double mat2[3][3]; - double den = atan(a*(M_PI/9)) + atan(a*(2*M_PI/9 - (M_PI/9))); + double den = atan(a*(M_PI/9)) + atan(a*(M_PI/9)); // This matrix is used to "rotate" the triangle to get each vertex // as the "origin" of the mapping in turn @@ -368,17 +368,19 @@ double qmTriangleAngles (MTriangle *e) { double orientation; prosca(v12,v34,&orientation); - // If the if the triangle is "flipped" it's no good + // If the triangle is "flipped" it's no good if (orientation < 0) return -std::numeric_limits<double>::max(); double c; prosca(v1,v2,&c); double x = acos(c)-M_PI/3; - double quality = (atan(a*(x+M_PI/9)) + atan(a*(2*M_PI/9 - (x+M_PI/9))))/den; + printf("Angle %g ", (x+M_PI/3)/M_PI*180); + double quality = (atan(a*(x+M_PI/9)) + atan(a*(M_PI/9-x)))/den; + printf("Quality %g\n",quality); worst_quality = std::min(worst_quality, quality); } - + //printf("\n"); return worst_quality; } @@ -405,10 +407,11 @@ double qmQuadrangleAngles (MQuadrangle *e) { e->getJacobian(u[i], v[i], 0, mat); e->getPrimaryJacobian(u[i],v[i],0,mat2); - // for (int j = 0; j < i; j++) { - //matmat(rot,mat,tmp); - // memcpy(mat, tmp, sizeof(mat)); - // } + //for (int j = 0; j < i; j++) { + // matmat(rot,mat,tmp); + // memcpy(mat, tmp, sizeof(mat)); + //} + //get angle double v1[3] = {mat[0][0], mat[0][1], mat[0][2] }; double v2[3] = {mat[1][0], mat[1][1], mat[1][2] }; @@ -432,7 +435,7 @@ double qmQuadrangleAngles (MQuadrangle *e) { double c; prosca(v1,v2,&c); - printf("%g %g\n",c,acos(c)*180/M_PI); + printf("Youhou %g %g\n",c,acos(c)*180/M_PI); double x = fabs(acos(c))-M_PI/2; double quality = (atan(a*(x+M_PI/4)) + atan(a*(2*M_PI/4 - (x+M_PI/4))))/den; worst_quality = std::min(worst_quality, quality);