Gmsh划分四边形、六面体网格
结构网格与非结构网格的定义比较模糊,从其特点来讲,结构网格是其节点位置可预测,网格几何结构一定。非结构网格是节点位置不可预测,网格几何不是重复的。从应用角度来说,结构网格指四边形和六面体。简单几何易于生成结构网格,复杂几何很难生成结构网格。
从生成算法来讲,结构网格的算法有:插值法、拉伸、扫略等。非结构网格的算法有:Delaunay、AFT、四叉树、八叉树等。本文仅描述使用Gmsh生成四边形和六面体的方法。
此方法通过指定“相对着的线”上节点数一致,指定“面上的Corner点”(超过四条边界的面),指定“体上的Corner”(超过八个边界面的体)。如下,设置正方形四条边上的节点数为20,
//面由四条边组成,每条边20个网格,图 1 double lc = 1e-2; gmsh::model::geo::addPoint(0, 0, 0, lc, 1); gmsh::model::geo::addPoint(10, 0, 0, lc, 2); gmsh::model::geo::addPoint(10, 10, 0, lc, 3); gmsh::model::geo::addPoint(0, 10, 0, lc, 4); gmsh::model::geo::addLine(1, 2, 1); gmsh::model::geo::addLine(3, 2, 2); gmsh::model::geo::addLine(3, 4, 3); gmsh::model::geo::addLine(4, 1, 4); gmsh::model::geo::addCurveLoop({ 4, 1, -2, 3 }, 1); gmsh::model::geo::addPlaneSurface({ 1 }, 1); gmsh::model::geo::mesh::setTransfiniteCurve(1, 20); gmsh::model::geo::mesh::setTransfiniteCurve(2, 20); gmsh::model::geo::mesh::setTransfiniteCurve(3, 20); gmsh::model::geo::mesh::setTransfiniteCurve(4, 20); gmsh::model::geo::mesh::setTransfiniteSurface(1);gmsh::model::geo::mesh::setRecombine(2, 1);
下边代码展示,由5条边界组成的面,
//图 2 double lc = 1; gmsh::model::geo::addPoint(0, 0, 0, lc, 1); gmsh::model::geo::addPoint(10, 0, 0, lc, 2); gmsh::model::geo::addPoint(10, 10, 0, lc, 3); gmsh::model::geo::addPoint(0, 10, 0, lc, 4); gmsh::model::geo::addPoint(-5, 5, 0, lc, 5); gmsh::model::geo::addLine(1, 2, 1); gmsh::model::geo::addLine(2, 3, 2); gmsh::model::geo::addLine(3, 4, 3); gmsh::model::geo::addLine(4, 5, 4);//将Line 4,5合为一条边 gmsh::model::geo::addLine(5, 1, 5); gmsh::model::geo::addCurveLoop({1,2,3,4,5 }, 1); gmsh::model::geo::addPlaneSurface({ 1 }, 1); gmsh::model::geo::mesh::setTransfiniteCurve(1, 20); gmsh::model::geo::mesh::setTransfiniteCurve(2, 20); gmsh::model::geo::mesh::setTransfiniteCurve(3, 20); gmsh::model::geo::mesh::setTransfiniteCurve(4, 11); gmsh::model::geo::mesh::setTransfiniteCurve(5, 10); //两条直线公用一个点,故加起来得比20大1 gmsh::model::geo::mesh::setTransfiniteSurface(1, "Left", {1,2,3,4});//指示四个角点 gmsh::model::geo::mesh::setRecombine(2, 1);
以下代码,由setTransfiniteAutomatic自动设置由8个点8个面组成的体。
double lc = 1;gmsh::model::occ::addBox(0, 0, 0, 10, 10, 10, 1);gmsh::model::occ::synchronize();gmsh::model::mesh::setTransfiniteAutomatic();
代码设置volume的Transfinite不太容易,编号太多。以下代码读入非8个面的体(IGS文件),使用Gmsh的图形化窗口设置其Transfinite。设置比较繁琐,总而言之,保证面上相对的边上节点数量一致,4个角点设置正确。
//网格 图 3,图 4 //注意此处容差设置,否则读入的几何线段重合。图 5,图 6 //注意设置 “缝合面”,否则读入的只是面,面不闭合。 //这两项均可在图形界面中设置,‘Tools->Options->Geometry->General’ gmsh::option::setNumber("Geometry.Tolerance", 0.1); gmsh::option::setNumber("Geometry.OCCSewFaces",1); std::vector<std::pair<int, int> > v; try { gmsh::model::occ::importShapes("solid8.igs", v);//此处可以设置只将solid导入,或者将solid下的点、线、面、shell都导入。 } catch (...) { gmsh::logger::write("Could not load STEP file: bye!"); gmsh::finalize(); return 0; } gmsh::model::occ::addSurfaceLoop({1,2,3,4,5,6,7,8},100,true); gmsh::model::occ::addVolume({ 100 }, 300); gmsh::model::occ::synchronize(); gmsh::model::mesh::generate(3);
2. Quasi-structured Quad 算法
对于2维几何可以使用Quasi-structured Quad生成四边形。如下代码,读入IGS,并划分为四边形。
//图 7,图 8//读入IGS,如上gmsh::model::occ::synchronize();gmsh::option::setNumber("Mesh.Algorithm", 11);gmsh::model::mesh::generate(2);
3.拉伸、扫略方法
以面上网格,拉伸、扫略形成四面体。如下代码:
gmsh::initialize(argc, argv); gmsh::model::add("t18"); gmsh::model::occ::addRectangle(0, 0, 0, 10, 10, 100); double h = 10; std::vector<std::pair<int, int> > ov; std::vector<int> nums; std::vector<double> heights; nums.push_back(10); //拉伸几何的同时,也拉伸网格 gmsh::model::occ::extrude({ {2, 100} }, 0, 0, h, ov, nums, heights,true); gmsh::model::occ::synchronize(); //gmsh::option::setNumber("Mesh.MeshSizeMin", 1.0); //gmsh::option::setNumber("Mesh.MeshSizeMax", 3.0); gmsh::option::setNumber("Mesh.Algorithm", 8); //此处若使用“Quasi-structured Quad”会出错 gmsh::model::mesh::setRecombine(2, 100);gmsh::model::mesh::generate(3);
合并算法不能保证生成质量优秀的四边形,也不能保证全部合并为四边形。如果能在面上使用“Quasi-structured Quad”算法,再拉伸。但是,此时总会出现外边一层单元无法生成,Debug提示“Could not find extruded vertex (-3.333641223427529, 20, -2.490304324894331)”。应该是没有找到合适的点。
如果有朋友知道,烦请不吝赐教。
路漫漫其修远兮,共勉 。
参考:
Gmsh 文档
Gmsh Source Code
文章来源:有限元仿真技术交流平台