之前因为成功调用了Gmsh的API进行网格划分,效果也还不错,考虑到都是三角形或者四面体,突然有种想法就是怎么实现四边形或者六面体,在查看Gmsh的PDF文档时候发现,Gmsh和Netgen一样具有将三角形合并为四边形的功能,于是我在参考Gmsh的C++例子中找到了一些有效信息,这些例子在PDF文档中也提到过,核心就是recombine选项开启,例子如下:
//
// -----------------------------------------------------------------------------
//
// Gmsh C++ tutorial 11
//
// Unstructured quadrangular meshes
//
// -----------------------------------------------------------------------------
#include
#include
int main(int argc, char **argv)
{
gmsh::initialize();
gmsh::model::add("t11");
// We have seen in tutorials `t3.cpp' and `t6.cpp' that extruded and
// transfinite meshes can be "recombined" into quads, prisms or
// hexahedra. Unstructured meshes can be recombined in the same way. Let's
// define a simple geometry with an analytical mesh size field:
int p1 = gmsh::model::geo::addPoint(-1.25, -.5, 0);
int p2 = gmsh::model::geo::addPoint(1.25, -.5, 0);
int p3 = gmsh::model::geo::addPoint(1.25, 1.25, 0);
int p4 = gmsh::model::geo::addPoint(-1.25, 1.25, 0);
int l1 = gmsh::model::geo::addLine(p1, p2);
int l2 = gmsh::model::geo::addLine(p2, p3);
int l3 = gmsh::model::geo::addLine(p3, p4);
int l4 = gmsh::model::geo::addLine(p4, p1);
int cl = gmsh::model::geo::addCurveLoop({l1, l2, l3, l4});
int pl = gmsh::model::geo::addPlaneSurface({cl});
gmsh::model::geo::synchronize();
gmsh::model::mesh::field::add("MathEval", 1);
gmsh::model::mesh::field::setString(
1, "F", "0.01*(1.0+30.*(y-x*x)*(y-x*x) + (1-x)*(1-x))");
gmsh::model::mesh::field::setAsBackgroundMesh(1);
// To generate quadrangles instead of triangles, we can simply add
gmsh::model::mesh::setRecombine(2, pl);
// If we'd had several surfaces, we could have used the global option
// "Mesh.RecombineAll":
//
// gmsh::option::setNumber("Mesh.RecombineAll", 1);
// The default recombination algorithm is called "Blossom": it uses a minimum
// cost perfect matching algorithm to generate fully quadrilateral meshes from
// triangulations. More details about the algorithm can be found in the
// following paper: J.-F. Remacle, J. Lambrechts, B. Seny, E. Marchandise,
// A. Johnen and C. Geuzaine, "Blossom-Quad: a non-uniform quadrilateral mesh
// generator using a minimum cost perfect matching algorithm", International
// Journal for Numerical Methods in Engineering 89, pp. 1102-1119, 2012.
// For even better 2D (planar) quadrilateral meshes, you can try the
// experimental "Frontal-Delaunay for quads" meshing algorithm, which is a
// triangulation algorithm that enables to create right triangles almost
// everywhere: J.-F. Remacle, F. Henrotte, T. Carrier-Baudouin, E. Bechet,
// E. Marchandise, C. Geuzaine and T. Mouton. A frontal Delaunay quad mesh
// generator using the L^inf norm. International Journal for Numerical Methods
// in Engineering, 94, pp. 494-512, 2013. Uncomment the following line to try
// the Frontal-Delaunay algorithms for quads:
//
// gmsh::option::setNumber("Mesh.Algorithm", 8);
// The default recombination algorithm might leave some triangles in the mesh,
// if recombining all the triangles leads to badly shaped quads. In such
// cases, to generate full-quad meshes, you can either subdivide the resulting
// hybrid mesh (with `Mesh.SubdivisionAlgorithm' set to 1), or use the
// full-quad recombination algorithm, which will automatically perform a
// coarser mesh followed by recombination, smoothing and
// subdivision. Uncomment the following line to try the full-quad algorithm:
//
// gmsh::option::setNumber("Mesh.RecombinationAlgorithm", 2); // or 3
// You can also set the subdivision step alone, with
//
// gmsh::option::setNumber("Mesh.SubdivisionAlgorithm", 1);
gmsh::model::mesh::generate(2);
// Note that you could also apply the recombination algorithm and/or the
// subdivision step explicitly after meshing, as follows:
//
// gmsh::model::mesh::generate(2);
// gmsh::model::mesh::recombine();
// gmsh::option::setNumber("Mesh.SubdivisionAlgorithm", 1);
// gmsh::model::mesh::refine();
// Launch the GUI to see the results:
std::set
if(!args.count("-nopopup")) gmsh::fltk::run();
gmsh::finalize();
return 0;
}
//
大概可以总结为2句:gmsh::model::geo::mesh::setRecombine(dim,tag),当前仅支持dim = 2; gmsh::option::setNumber("Mesh.RecombineAll", 1);对有所的surface有效。划分完成后,获取Node 和 Eement的方法可以参考我前面的文章,比较简单。OSG显示效果展示如下:
效果中可以看见,大部分的三角形合并成了四边形,但是也有少数的三角形没有成功,这个问题暂时不得而知,在Gmsh中也出现过这样的现象,所以暂时不作处理。
最近参考了下开源的SALOME软件,SALOME是一个基于Opencascade内核的CAD/CAE程序,其网格划分功能还是很丰富的,而且效果好像也不错,考虑将其SMESH集成进来。如果有知道怎么处理部分三角形合并失败的朋友、老师,请指教,感激不尽。