diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp index a49e912c7dffa3919d0a7923260fd3ea45f6fc74..ecb99aa999c04acde5613684e5ae473a596f3119 100644 --- a/Mesh/HighOrder.cpp +++ b/Mesh/HighOrder.cpp @@ -396,7 +396,8 @@ void getFaceVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &vf, faceContainer &faceVertices, - bool linear, int nPts = 1){ + bool linear, int nPts = 1) { + Double_Matrix points; int start = 0; @@ -454,11 +455,21 @@ void getFaceVertices(GFace *gf, v = new MVertex(pc.x(), pc.y(), pc.z(), gf); } else{ + + // SPoint3 pos; + // incomplete->pnt(t1,t2,0.,pos); + // double X(pos.x()); + // double Y(pos.y()); + // double Z(pos.z()); + + double X(0),Y(0),Z(0),GUESS[2]={0,0}; for (int j=0; j<incomplete->getNumVertices(); j++){ + double sf ; incomplete->getShapeFunction(j,t1,t2,0,sf); MVertex *vt = incomplete->getVertex(j); + X += sf * vt->x(); Y += sf * vt->y(); Z += sf * vt->z(); @@ -526,6 +537,7 @@ void getFaceVertices(GFace *gf, void getFaceVertices(GFace *gf, MElement *ele, std::vector<MVertex*> &vf, faceContainer &faceVertices, bool linear, int nPts = 1) { + Double_Matrix points; int start = 0; @@ -648,7 +660,7 @@ void reorientTrianglePoints(std::vector<MVertex*>& vtcs,int orientation,bool swa // for (int i=0;i<3;i++) tmp[(i+orientation)%3] = vtcs[i]; - for (int i=0;i<3;i++) tmp[i] = vtcs[(i+orientation)%3]; + for (int i=0;i<3;i++) tmp[(i+orientation)%3] = vtcs[i]; // normal swap @@ -669,9 +681,34 @@ void reorientTrianglePoints(std::vector<MVertex*>& vtcs,int orientation,bool swa // KH: check face orientation wrt element ... void getFaceVertices(GRegion *gr, MElement *ele, std::vector<MVertex*> &vf, - faceContainer &faceVertices, bool linear, int nPts = 1) + faceContainer &faceVertices, + edgeContainer& edgeVertices, + bool linear, int nPts = 1) { + + Double_Matrix points; + int start = 0; + + switch (nPts){ + case 2 : + points = gmshFunctionSpaces::find(MSH_TRI_10).points; + start = 9; + break; + case 3 : + points = gmshFunctionSpaces::find(MSH_TRI_15).points; + start = 12; + break; + case 4 : + points = gmshFunctionSpaces::find(MSH_TRI_21).points; + start = 15; + break; + default : + // do nothing (e.g. for quad faces) + break; + } + + for(int i = 0; i < ele->getNumFaces(); i++){ MFace face = ele->getFace(i); // std::vector<MVertex*> p; @@ -696,31 +733,83 @@ void getFaceVertices(GRegion *gr, MElement *ele, std::vector<MVertex*> &vf, vf.insert(vf.end(), vtcs.begin(), vtcs.end()); } else{ - std::vector<MVertex*>& vtcs = faceVertices[face]; + std::vector<MVertex*>& vtcs = faceVertices[face]; if(face.getNumVertices() == 3){ // triangles - for(int j = 0; j < nPts; j++){ - for(int k = 0 ; k < nPts - j - 1; k++){ - - // KH: inverted direction to stick with triangle vertex numbering - // - // 2 - // | \ - // 0 - 1 - // - // double t1 = (double)(j + 1) / (nPts + 1); - // double t2 = (double)(k + 1) / (nPts + 1); - double t1 = (double)(k + 1) / (nPts + 1); - double t2 = (double)(j + 1) / (nPts + 1); - SPoint3 pc = face.interpolate(t1, t2); - MVertex *v = new MVertex(pc.x(), pc.y(), pc.z(), gr); - // faceVertices[p].push_back(v); - vtcs.push_back(v); - gr->mesh_vertices.push_back(v); - vf.push_back(v); + // construct incomplete element to take into account curved edges on surface boundaries + + std::vector<MVertex*> hoEdgeNodes; + + for (int i=0;i<3;i++) { + + MVertex* v0 = face.getVertex(i); + MVertex* v1 = face.getVertex((i+1)%3); + + edgeContainer::iterator eIter = edgeVertices.find(std::pair<MVertex*,MVertex*>(std::min(v0,v1),std::max(v0,v1))); + + if (eIter == edgeVertices.end()) { + printf("Could not find ho nodes for an edge"); } + + if (v0 == eIter->first.first) hoEdgeNodes.insert(hoEdgeNodes.end(),eIter->second.begin(),eIter->second.end()); + else hoEdgeNodes.insert(hoEdgeNodes.end(),eIter->second.rbegin(),eIter->second.rend()); } + + MTriangleN incomplete(face.getVertex(0),face.getVertex(1),face.getVertex(2),hoEdgeNodes,nPts+1); + + double X(0),Y(0),Z(0); + + for (int k=start;k<points.size1();k++) { + + double t1 = points(k,0); + double t2 = points(k,1); + + + for (int j=0; j<incomplete.getNumVertices(); j++){ + + double sf ; incomplete.getShapeFunction(j,t1,t2,0,sf); + MVertex *vt = incomplete.getVertex(j); + + X += sf * vt->x(); + Y += sf * vt->y(); + Z += sf * vt->z(); + } + + MVertex* v = new MVertex(X,Y,Z,gr); + + +// SPoint3 pc = face.interpolate(t1, t2); +// MVertex *v = new MVertex(pc.x(), pc.y(), pc.z(), gr); + // faceVertices[p].push_back(v); + vtcs.push_back(v); + gr->mesh_vertices.push_back(v); + vf.push_back(v); + } + +// for(int j = 0; j < nPts; j++){ +// for(int k = 0 ; k < nPts - j - 1; k++){ + +// // KH: inverted direction to stick with triangle vertex numbering +// // is not consistent with function space definitions for p>4 +// // +// // 2 +// // | \ +// // 0 - 1 +// // +// // double t1 = (double)(j + 1) / (nPts + 1); +// // double t2 = (double)(k + 1) / (nPts + 1); +// double t1 = (double)(k + 1) / (nPts + 1); +// double t2 = (double)(j + 1) / (nPts + 1); + +// SPoint3 pc = face.interpolate(t1, t2); +// MVertex *v = new MVertex(pc.x(), pc.y(), pc.z(), gr); +// // faceVertices[p].push_back(v); +// vtcs.push_back(v); +// gr->mesh_vertices.push_back(v); +// vf.push_back(v); +// } +// } } else if(face.getNumVertices() == 4){ // quadrangles for(int j = 0; j < nPts; j++){ @@ -771,15 +860,22 @@ void getRegionVertices(GRegion *gr, const double t1 = points(k, 0); const double t2 = points(k, 1); const double t3 = points(k, 2); - double X(0),Y(0),Z(0); - for (int j=0; j<incomplete->getNumVertices(); j++){ - double sf ; incomplete->getShapeFunction(j,t1,t2,t3,sf); - MVertex *vt = incomplete->getVertex(j); - X += sf * vt->x(); - Y += sf * vt->y(); - Z += sf * vt->z(); - } - v = new MVertex(X,Y,Z, gr); + + SPoint3 pos; + incomplete->pnt(t1,t2,t3,pos); + + v = new MVertex(pos.x(),pos.y(),pos.z(),gr); + +// double X(0),Y(0),Z(0); +// for (int j=0; j<incomplete->getNumVertices(); j++){ +// double sf ; incomplete->getShapeFunction(j,t1,t2,t3,sf); +// MVertex *vt = incomplete->getVertex(j); +// X += sf * vt->x(); +// Y += sf * vt->y(); +// Z += sf * vt->z(); +// } +// + // v = new MVertex(X,Y,Z, gr); gr->mesh_vertices.push_back(v); vr.push_back(v); } @@ -880,12 +976,12 @@ void setHighOrder(GRegion *gr, edgeContainer &edgeVertices, t->getVertex(3), ve[0], ve[1], ve[2], ve[3], ve[4], ve[5])); } else{ - getFaceVertices(gr, t, vf, faceVertices, linear, nPts); + getFaceVertices(gr, t, vf, faceVertices, edgeVertices, linear, nPts); ve.insert(ve.end(), vf.begin(), vf.end()); MTetrahedronN incpl (t->getVertex(0), t->getVertex(1), t->getVertex(2), t->getVertex(3), ve, nPts + 1); - getRegionVertices(gr, &incpl, t, vr, linear, nPts); - ve.insert(ve.end(), vr.begin(), vr.end()); + // getRegionVertices(gr, &incpl, t, vr, linear, nPts); + // ve.insert(ve.end(), vr.begin(), vr.end()); tetrahedra2.push_back (new MTetrahedronN(t->getVertex(0), t->getVertex(1), t->getVertex(2), t->getVertex(3), ve, nPts + 1)); @@ -908,7 +1004,7 @@ void setHighOrder(GRegion *gr, edgeContainer &edgeVertices, ve[11])); } else{ - getFaceVertices(gr, h, vf, faceVertices, linear, nPts); + getFaceVertices(gr, h, vf, faceVertices, edgeVertices, linear, nPts); SPoint3 pc = h->barycenter(); MVertex *v = new MVertex(pc.x(), pc.y(), pc.z(), gr); gr->mesh_vertices.push_back(v); @@ -935,7 +1031,7 @@ void setHighOrder(GRegion *gr, edgeContainer &edgeVertices, ve[0], ve[1], ve[2], ve[3], ve[4], ve[5], ve[6], ve[7], ve[8])); } else{ - getFaceVertices(gr, p, vf, faceVertices, linear, nPts); + getFaceVertices(gr, p, vf, faceVertices, edgeVertices, linear, nPts); prisms2.push_back (new MPrism18(p->getVertex(0), p->getVertex(1), p->getVertex(2), p->getVertex(3), p->getVertex(4), p->getVertex(5), @@ -958,7 +1054,7 @@ void setHighOrder(GRegion *gr, edgeContainer &edgeVertices, ve[3], ve[4], ve[5], ve[6], ve[7])); } else{ - getFaceVertices(gr, p, vf, faceVertices, linear, nPts); + getFaceVertices(gr, p, vf, faceVertices, edgeVertices, linear, nPts); pyramids2.push_back (new MPyramid14(p->getVertex(0), p->getVertex(1), p->getVertex(2), p->getVertex(3), p->getVertex(4), ve[0], ve[1], ve[2],