diff --git a/Geo/FEdge.cpp b/Geo/FEdge.cpp index 422287583a777927b9bcd0820261ae8456522b35..34ed1e4667dd1b6e9310f52f2d08395937855bb5 100644 --- a/Geo/FEdge.cpp +++ b/Geo/FEdge.cpp @@ -3,6 +3,20 @@ #if defined(HAVE_FOURIER_MODEL) +FEdge::FEdge(GModel *model, FM_Edge* edge_, int tag, GVertex *v0, GVertex *v1) + : GEdge(model, tag, v0, v1), edge(edge_), face(0), edgeNum(-1) +{ + //meshAttributes.Method = TRANSFINI; + //meshAttributes.coeffTransfinite = 1.; + //meshAttributes.nbPointsTransfinite = 10; +} + +FEdge::FEdge(GModel *model, FM_Face* face_, int edgeNum_, int tag, GVertex *v0, + GVertex *v1) + : GEdge(model, tag, v0, v1), edge(0), face(face_), edgeNum(edgeNum_) +{ +} + Range<double> FEdge::parBounds(int i) const { return(Range<double>(0.,1.)); diff --git a/Geo/FEdge.h b/Geo/FEdge.h index e23dc3d608053b4b6bf6c1e04aa815d31f7aee9e..6ff0bb9987f3f9ce435d54841d4c041ebe637695 100644 --- a/Geo/FEdge.h +++ b/Geo/FEdge.h @@ -18,11 +18,9 @@ class FEdge : public GEdge { FM_Face* face; int edgeNum; public: - FEdge(GModel *model, FM_Edge* edge_, int tag, GVertex *v0, GVertex *v1) : - GEdge(model, tag, v0, v1), edge(edge_), face(0), edgeNum(-1) {} + FEdge(GModel *model, FM_Edge* edge_, int tag, GVertex *v0, GVertex *v1); FEdge(GModel *model, FM_Face* face_, int edgeNum_, int tag, GVertex *v0, - GVertex *v1) : GEdge(model, tag, v0, v1), edge(0), face(face_), - edgeNum(edgeNum_) {} + GVertex *v1); virtual ~FEdge() {} double period() const { throw ; } virtual bool periodic(int dim=0) const { return false; } diff --git a/Geo/GEdge.cpp b/Geo/GEdge.cpp index 3e49dfa02fc7ea8bc9f8112cfbd38dd6ed744928..1073a0add53d4c224b652c6b36100f8876d2449b 100644 --- a/Geo/GEdge.cpp +++ b/Geo/GEdge.cpp @@ -1,4 +1,4 @@ -// $Id: GEdge.cpp,v 1.27 2007-05-07 11:40:02 remacle Exp $ +// $Id: GEdge.cpp,v 1.28 2007-05-10 22:08:03 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -119,16 +119,16 @@ SVector3 GEdge::secondDer(double par) const { // use central differences const double eps = 1.e-3; - SVector3 x1 = firstDer(par-eps); - SVector3 x2 = firstDer(par+eps); - return 500*(x2-x1); + SVector3 x1 = firstDer(par - eps); + SVector3 x2 = firstDer(par + eps); + return 500 * (x2 - x1); } -// Reparmaterize the point onto the given face. SPoint2 GEdge::reparamOnFace(GFace *face, double epar,int dir) const { - const GPoint p3 = point (epar); - SPoint3 sp3(p3.x(),p3.y(),p3.z()); + // reparmaterize the point onto the given face. + const GPoint p3 = point(epar); + SPoint3 sp3(p3.x(), p3.y(), p3.z()); return face->parFromPoint(sp3); } @@ -153,11 +153,12 @@ double GEdge::curvature(double par) const n1.normalize(); n2.normalize(); - const double one_over_D = 1./D; - SVector3 d = one_over_D*(n2-n1); + const double one_over_D = 1. / D; + SVector3 d = one_over_D * (n2 - n1); return norm(d); } -bool GEdge::is_mesh_degenerated() const { - return (v0==v1 && mesh_vertices.size()<2); +bool GEdge::is_mesh_degenerated() const +{ + return (v0 == v1 && mesh_vertices.size() < 2); } diff --git a/Geo/GModelIO_Mesh.cpp b/Geo/GModelIO_Mesh.cpp index ba7fbf0fa4b75c076788c4aeb4e66e3a955556c1..b4ad68a2925c8b04ed389cedd679139f79fe6866 100644 --- a/Geo/GModelIO_Mesh.cpp +++ b/Geo/GModelIO_Mesh.cpp @@ -1,4 +1,4 @@ -// $Id: GModelIO_Mesh.cpp,v 1.16 2007-05-02 07:59:27 geuzaine Exp $ +// $Id: GModelIO_Mesh.cpp,v 1.17 2007-05-10 22:08:03 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -1364,6 +1364,43 @@ int GModel::writeUNV(const std::string &name, bool saveAll, double scalingFactor } fprintf(fp, "%6d\n", -1); + // save groups of nodes for physical lines and physical surfaces + bool saveGroupsOfNodes = false; // add option in CTX+GUI for this + if(saveGroupsOfNodes){ + fprintf(fp, "%6d\n", -1); + fprintf(fp, "%6d\n", 2477); + std::map<int, std::vector<GEntity*> > groups[4]; + getPhysicalGroups(groups); + for(int dim = 1; dim <= 2; dim++){ + for(std::map<int, std::vector<GEntity*> >::iterator it = groups[dim].begin(); + it != groups[dim].end(); it++){ + std::set<MVertex*> nodes; + for(unsigned int i = 0; i < it->second.size(); i++){ + if(dim == 1){ + GEdge *ge = (GEdge*)it->second[i]; + for(unsigned int j = 0; j < ge->lines.size(); j++) + for(int k = 0; k < ge->lines[j]->getNumVertices(); k++) + nodes.insert(ge->lines[j]->getVertex(k)); + } + else if(dim == 2){ + GFace *gf = (GFace*)it->second[i]; + for(unsigned int j = 0; j < gf->triangles.size(); j++) + for(int k = 0; k < gf->triangles[j]->getNumVertices(); k++) + nodes.insert(gf->triangles[j]->getVertex(k)); + for(unsigned int j = 0; j < gf->quadrangles.size(); j++) + for(int k = 0; k < gf->quadrangles[j]->getNumVertices(); k++) + nodes.insert(gf->quadrangles[j]->getVertex(k)); + } + } + // put actual format of dataset in here + printf("physical %d : %d nodes\n", it->first, nodes.size()); + for(std::set<MVertex*>::iterator it2 = nodes.begin(); it2 != nodes.end(); it2++) + printf("node %6d\n", (*it2)->getNum()); + } + } + fprintf(fp, "%6d\n", -1); + } + fclose(fp); return 1; } diff --git a/Geo/GRegion.cpp b/Geo/GRegion.cpp index b79f885ac0d1eee60859815856079064ca5c7830..cd856b6d4f6f74d11ba1264bd8119d4f24960c91 100644 --- a/Geo/GRegion.cpp +++ b/Geo/GRegion.cpp @@ -1,4 +1,4 @@ -// $Id: GRegion.cpp,v 1.15 2006-12-16 14:37:20 geuzaine Exp $ +// $Id: GRegion.cpp,v 1.16 2007-05-10 22:08:03 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -120,13 +120,13 @@ void GRegion::deleteMeshPartitions() std::list<GEdge*> GRegion::edges() const { std::list<GEdge*> e; - std::list<GFace *>::const_iterator it = l_faces.begin(); + std::list<GFace*>::const_iterator it = l_faces.begin(); while(it != l_faces.end()){ std::list<GEdge*> e2; e2 = (*it)->edges(); std::list<GEdge*>::const_iterator it2 = e2.begin(); while (it2 != e2.end()){ - if (std::find(e.begin(),e.end(),*it2) == e.end()) + if (std::find(e.begin(), e.end(), *it2) == e.end()) e.push_back(*it2); ++it2; } @@ -134,3 +134,17 @@ std::list<GEdge*> GRegion::edges() const } return e; } + +bool GRegion::edgeConnected(GRegion *r) const +{ + std::list<GEdge*> e = edges(); + std::list<GEdge*> e2 = r->edges(); + + std::list<GEdge*>::const_iterator it = e.begin(); + while(it != e.end()){ + if(std::find(e2.begin(), e2.end(), *it) != e2.end()) + return true; + ++it; + } + return false; +} diff --git a/Geo/GRegion.h b/Geo/GRegion.h index 2d93c161dd016151f6c7f2f7572e23384f6b6708..8a6cda9a180dc69d790811b909e235def492aded 100644 --- a/Geo/GRegion.h +++ b/Geo/GRegion.h @@ -43,6 +43,9 @@ class GRegion : public GEntity { // The bounding box virtual SBoundingBox3d bounds() const; + // Checks if the region is connected to another region by an edge + bool edgeConnected(GRegion *r) const; + // Recompute the mesh partitions defined on this region. void recomputeMeshPartitions(); diff --git a/Geo/Makefile b/Geo/Makefile index 269b4c6743844c36c2e5b49d49e11173af825bda..f70e8ccd1efd8a1ee8cca65b69463cc8e796ac63 100644 --- a/Geo/Makefile +++ b/Geo/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.145 2007-05-05 10:24:53 geuzaine Exp $ +# $Id: Makefile,v 1.146 2007-05-10 22:08:03 geuzaine Exp $ # # Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle # @@ -223,7 +223,16 @@ GModelIO_F.o: GModelIO_F.cpp GModel.h GVertex.h GEntity.h Range.h \ GRegion.h ../Common/Message.h ../Common/Views.h ../Common/ColorTable.h \ ../Common/VertexArray.h ../Common/SmoothData.h \ ../Common/AdaptiveViews.h ../Common/GmshMatrix.h FFace.h FEdge.h \ - FVertex.h ../Mesh/meshGFace.h + FVertex.h ../Mesh/meshGFace.h GModelIO_F.h \ + ../contrib/FourierModel/FM_Reader.h ../contrib/FourierModel/Curve.h \ + ../contrib/FourierModel/Patch.h ../contrib/FourierModel/FM_Info.h \ + ../contrib/FourierModel/FM_Info.h ../contrib/FourierModel/ExactPatch.h \ + ../contrib/FourierModel/Patch.h \ + ../contrib/FourierModel/ContinuationPatch.h \ + ../contrib/FourierModel/Patch.h ../contrib/FourierModel/FM_Info.h \ + ../contrib/FourierModel/FM_Face.h ../contrib/FourierModel/Patch.h \ + ../contrib/FourierModel/FM_Edge.h ../contrib/FourierModel/Curve.h \ + ../contrib/FourierModel/FM_Vertex.h GModelIO_CGNS.o: GModelIO_CGNS.cpp GModel.h GVertex.h GEntity.h Range.h \ SPoint3.h SBoundingBox3d.h ../Common/GmshDefines.h MVertex.h GPoint.h \ SPoint2.h GEdge.h SVector3.h MElement.h MEdge.h ../Common/Hash.h \ diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp index eaf9ffe446a328a3ff34f971e199700b00841472..9a5285a7a77e9c78fef382286b3706161c24cc2f 100644 --- a/Mesh/Generator.cpp +++ b/Mesh/Generator.cpp @@ -1,4 +1,4 @@ -// $Id: Generator.cpp,v 1.118 2007-04-20 07:11:26 geuzaine Exp $ +// $Id: Generator.cpp,v 1.119 2007-05-10 22:08:03 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -232,6 +232,14 @@ void Mesh2D() Msg(STATUS1, "Mesh"); } + +void FindConnectedRegions(std::vector<GRegion*> &delaunay, + std::vector<std::vector<GRegion*> > &connected) +{ + // FIXME: need to split region vector into connected components here! + connected.push_back(delaunay); +} + void Mesh3D() { if(TooManyElements(3)) return; @@ -249,8 +257,13 @@ void Mesh3D() std::vector<GRegion*> delaunay; std::for_each(GMODEL->firstRegion(), GMODEL->lastRegion(), meshGRegion(delaunay)); - // and finally mesh the delaunay regions (again, this is global) - MeshDelaunayVolume(delaunay); + // and finally mesh the delaunay regions (again, this is global; but + // we mesh each connected part separately for performance and mesh + // quality reasons) + std::vector<std::vector<GRegion*> > connected; + FindConnectedRegions(delaunay, connected); + for(unsigned int i = 0; i < connected.size(); i++) + MeshDelaunayVolume(connected[i]); double t2 = Cpu(); CTX.mesh_timer[2] = t2 - t1; diff --git a/Mesh/meshGRegion.cpp b/Mesh/meshGRegion.cpp index e6e611f8191763d543a8db9044567687a4b3c3e3..8b07351f4b87c6d90165d172c5ebb741e8b40c7d 100644 --- a/Mesh/meshGRegion.cpp +++ b/Mesh/meshGRegion.cpp @@ -1,4 +1,4 @@ -// $Id: meshGRegion.cpp,v 1.29 2007-03-11 20:18:58 geuzaine Exp $ +// $Id: meshGRegion.cpp,v 1.30 2007-05-10 22:08:04 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -191,6 +191,9 @@ void MeshDelaunayVolume(std::vector<GRegion*> ®ions) Msg(GERROR, "Tetgen is not compiled in this version of Gmsh"); #else + for(unsigned int i = 0; i < regions.size(); i++) + Msg(STATUS2, "Meshing volume %d (Delaunay)", regions[i]->tag()); + // put all the faces in the same model GRegion *gr = regions[0]; std::list<GFace*> faces = gr->faces(); @@ -494,9 +497,6 @@ void meshGRegion::operator() (GRegion *gr) if(ep && ep->mesh.ExtrudeMesh) return; - // Send a messsage to the GMSH environment - Msg(STATUS2, "Meshing volume %d", gr->tag()); - // destroy the mesh if it exists deMeshGRegion dem; dem(gr); @@ -523,6 +523,7 @@ void meshGRegion::operator() (GRegion *gr) #if !defined(HAVE_NETGEN) Msg(GERROR, "Netgen is not compiled in this version of Gmsh"); #else + Msg(STATUS2, "Meshing volume %d (Netgen)", gr->tag()); // orient the triangles of with respect to this region meshNormalsPointOutOfTheRegion(gr); std::vector<MVertex*> numberedV; diff --git a/Mesh/meshGRegionExtruded.cpp b/Mesh/meshGRegionExtruded.cpp index 4dabacb97d0d038fc71c9aa58751c410775d348b..5c01d7ebea07ba2c102cdcaa20065e479d3b8bef 100644 --- a/Mesh/meshGRegionExtruded.cpp +++ b/Mesh/meshGRegionExtruded.cpp @@ -1,4 +1,4 @@ -// $Id: meshGRegionExtruded.cpp,v 1.16 2007-05-08 07:21:00 geuzaine Exp $ +// $Id: meshGRegionExtruded.cpp,v 1.17 2007-05-10 22:08:06 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -387,51 +387,20 @@ void phase1(GRegion *gr, for(int k = 0; k < ep->mesh.NbElmLayer[j]; k++) { std::vector<MVertex*> v; if(getExtrudedVertices(from->triangles[i], ep, j, k, pos, v) == 6){ -#if 1 // this is the old version +#if 0 // old if(!edgeExists(v[0], v[4], edges)) createEdge(v[1], v[3], edges); if(!edgeExists(v[4], v[2], edges)) createEdge(v[1], v[5], edges); if(!edgeExists(v[3], v[2], edges)) createEdge(v[0], v[5], edges); -#else // new version from Michel Benhamou <mi.benham@free.fr> - int v0 = 0; - for(int l = 1; l < 6; l++){ - if(v[l] < v[v0]) v0 = l; - } - v0 = (v0 + 2) % 3; - int vn[6]; - for(int l = 0; l < 3; l++){ - vn[l] = (v0 + l) % 3; - vn[l + 3] = vn[l] + 3; - } - - //if(v[vn[1]] < v[vn[0]]){ - if(!edgeExists(v[vn[0]], v[vn[4]], edges)) - createEdge(v[vn[1]], v[vn[3]], edges); - //} - //else{ - // if(!edgeExists(v[vn[1]], v[vn[3]], edges)) - // createEdge(v[vn[0]], v[vn[4]], edges); - //} - - //if(v[vn[1]] < v[vn[4]]){ - if(!edgeExists(v[vn[4]], v[vn[2]], edges)) - createEdge(v[vn[1]], v[vn[5]], edges); - //} - //else{ - // if(!edgeExists(v[vn[1]], v[vn[5]], edges)) - // createEdge(v[vn[4]], v[vn[2]], edges); - //} - - if(v[vn[0]] < v[vn[3]]){ - if(!edgeExists(v[vn[3]], v[vn[2]], edges)) - createEdge(v[vn[0]], v[vn[5]], edges); - } - else{ - if(!edgeExists(v[vn[0]], v[vn[5]], edges)) - createEdge(v[vn[3]], v[vn[2]], edges); - } +#else // new from Michel Benhamou + if(v[1] < v[0]) createEdge(v[1], v[3], edges); + else createEdge(v[0], v[4], edges); + if(v[1] < v[2]) createEdge(v[1], v[5], edges); + else createEdge(v[4], v[2], edges); + if(v[0] < v[2]) createEdge(v[0], v[5], edges); + else createEdge(v[3], v[2], edges); #endif } } diff --git a/Mesh/meshGRegionTransfinite.cpp b/Mesh/meshGRegionTransfinite.cpp index f379f81f9f9aef53955f9215895a9c7ba9b67ce5..bcc0efcfbcc58ed45f6c102ebf152f46903ae959 100644 --- a/Mesh/meshGRegionTransfinite.cpp +++ b/Mesh/meshGRegionTransfinite.cpp @@ -1,4 +1,4 @@ -// $Id: meshGRegionTransfinite.cpp,v 1.6 2007-04-24 09:02:25 geuzaine Exp $ +// $Id: meshGRegionTransfinite.cpp,v 1.7 2007-05-10 22:08:06 geuzaine Exp $ // // Copyright (C) 1997-2007 C. Geuzaine, J.-F. Remacle // @@ -280,6 +280,8 @@ int MeshTransfiniteVolume(GRegion *gr) { if(gr->meshAttributes.Method != TRANSFINI) return 0; + Msg(STATUS2, "Meshing volume %d (transfinite)", gr->tag()); + std::list<GFace*> faces = gr->faces(); if(faces.size() != 5 && faces.size() != 6){ Msg(GERROR, "Transfinite algorithm only available for 5- and 6-face volumes"); diff --git a/doc/TODO b/doc/TODO index 1d7590e86855861a18a0f34b0e62fa1c61886088..b888e81e82e54ce39ca2aee88cab6f48992993f3 100644 --- a/doc/TODO +++ b/doc/TODO @@ -1,4 +1,14 @@ -$Id: TODO,v 1.57 2007-05-04 14:45:04 geuzaine Exp $ +$Id: TODO,v 1.58 2007-05-10 22:08:06 geuzaine Exp $ + +******************************************************************** + +add function to deform MESH with displacement post-pro view + +******************************************************************** + +3D Delaunay: precompute non-connected volumes and apply algo to each +non-connected aggregate. This will improve mesh quality and speed for +close non-connected objects. ********************************************************************