weihuayi的个人博客分享 http://blog.sciencenet.cn/u/weihuayi

博文

基于CGAL设计自己的网格生成与优化程序

已有 9395 次阅读 2010-9-14 09:56 |个人分类:CGAL|系统分类:科研笔记| 优化, CGAL, 网格生成

     希望基于CGAL,写一个自己的网格生成与优化程序。 先从2D的情形开始吧!
     首先从功能谈起。 这个程序要以文件形式输入区域信息,能够处理曲边的情形, 生成满足一定密度的Delaunay网格,作为一个初始的的有限元计算网格;然后,给定一个密度函数(连续的或者离散的), 再调用CVT,ODT方法优化网格,不断的重复这个过程序,直到满足一定的条件为止。

* 区域描述文件的数据格式:

采用sample.poly的数据格式,如下:

.poly files

  • First line: <# of vertices> <dimension (must be 2)> <# of attributes> <# of boundary markers (0 or 1)>
  • Following lines: <vertex #> <x> <y> [attributes] [boundary marker]
  • One line: <# of segments> <# of boundary markers (0 or 1)>
  • Following lines: <segment #> <endpoint> <endpoint> [boundary marker]
  • One line: <# of holes>
  • Following lines: <hole #> <x> <y>
  • One line: <# of regional attributes 
  • Following lines: <region #> <x> <y>
  # square.poly
   4 2 0 1
     1   -1 -1   1
     2   1 -1   1
     3   1 1   1
     4   -1 1   1
     4  1
     1   1 2   3
     2   2 3   4
     3   3 4   5
     4   4 1   6
     0

#2hexa_in_square.poly
     16     2     0     1
     1        0.0000000000        0.0000000000     1
     2        1.0000000000        0.0000000000     1
     3        1.0000000000        1.0000000000     1
     4        0.0000000000        1.0000000000     1
     5        0.1500000060        0.7500000000     1
     6        0.2002999932        0.6633999944     1
     7        0.3001999855        0.6639999747     1
     8        0.3499999940        0.7500000000     1
     9        0.3001999855        0.8360000253     1
    10        0.2002999932        0.8366000056     1
    11        0.5000000000        0.4000000060     1
    12        0.5503000021        0.3134000003     1
    13        0.6502000093        0.3140000105     1
    14        0.6999999881        0.4000000060     1
    15        0.6502000093        0.4860000014     1
    16        0.5503000021        0.4866000116     1
    16 1
    1    1 2    3
    2    2 3    4   
    3    3 4    5
    4     4 1    6
    5    5 6    7
    6    6 7    8
    7    7 8    9
    8    8 9    10
    9    9 10    11
    10    10 5    12
    11    11 12    13
    12    12 13    14
    13    13 14    15
    14    14 15    16
    15    15 16    17
    16    16 11    18
     2
     1        0.2500000000        0.7500000000
     2        0.6000000238        0.4000000060

如果想处理拥有曲边的区域情形, 首先要有一个对区域的多边形逼近, 再加上一个距离函数,能够把新生成的边界点投影到边界上。

在.poly文件当中,边界点的标记必须是1或2, 如果是1,表示它在整个网格生成过程中是固定的;如果是2,则在直边的情形下它是固定的,在曲边的情形下,它要被投回到边界上。

顶点和面要加入额外的信息。顶点要知道它是否在边界上,是否要投影回边界,对应一个尺寸函数值。面要知道它属于那个子区域。

* 算法的实现CGAL基础
    *读入区域文件。
    *设定限止边和种子
    *进行初始的剖分,形成一个均匀的网格
    *如果有曲边,把本就是曲边的点投影到曲边上。

     *根据密度函数插入新的节点,形成一个满足一定密度函数的网格

     *网格优化:CVT, ODT, distmesh

2, 输出数据的文件格式

3,可视化接口的实现

利用Geoview 来实现可视化。

2010.09.13

 昨天网格生成的程序可以运行了,在此基础之上就能进行更深入的学习和实验。

在用std::vector时,我先给这种类型的变量Vhs的长度设为n,然后又用push_back把读入的数据存在变量当中(实际上是存在n+1的位置上)。但我以为是存开头,用Vhs[0]从而导致访问的错误。最终的程序如下:


#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Constrained_Delaunay_triangulation_2.h>
#include <CGAL/Delaunay_mesher_2.h>

#include <CGAL/Triangulation_face_base_with_info_2.h>
#include <CGAL/Constrained_triangulation_face_base_2.h>
#include <CGAL/Delaunay_mesh_face_base_2.h>
#include <CGAL/Delaunay_mesh_size_criteria_2.h>

#include <CGAL/Triangulation_vertex_base_with_info_2.h>



#include <iostream>
#include <fstream>

#include <unistd.h> // for sleep()


#include <CGAL/IO/Geomview_stream.h>
#include <CGAL/IO/Triangulation_geomview_ostream_2.h>

#include <CGAL/Bbox_2.h>
#include <CGAL/Polygon_2_algorithms.h>

class Face_info
{
  int attribute;
public:
  Face_info():attribute(1){}
  Face_info(int a): attribute(a) {}
  int get_attribute()
  {
    return attribute;
  }
  void set_attribute(int a)
  {
    attribute = a;
  }

};

class Vertex_info
{
  int bd_flag;// 1:fixed point; 2:should project into boundary; 0: other points. 
public:
  Vertex_info():bd_flag(0){}
  Vertex_info(int bf):bd_flag(bf){}
  void set_bd_flag(int bf)
  {
    bd_flag = bf;
  }
  int get_bd_flag()
  {
    return bd_flag;
  }
};

typedef CGAL::Exact_predicates_inexact_constructions_kernel K;

typedef CGAL::Triangulation_vertex_base_with_info_2<Vertex_info,K> Vb;


typedef CGAL::Triangulation_face_base_with_info_2<Face_info,K> Fbbb;
typedef CGAL::Constrained_triangulation_face_base_2<K,Fbbb> Fbb;
typedef CGAL::Delaunay_mesh_face_base_2<K,Fbb> Fb;


typedef CGAL::Triangulation_data_structure_2<Vb, Fb> Tds;
typedef CGAL::Constrained_Delaunay_triangulation_2<K, Tds> CDT;
typedef CGAL::Delaunay_mesh_size_criteria_2<CDT> Criteria;
typedef CGAL::Delaunay_mesher_2<CDT, Criteria> Mesher;

typedef CDT::Vertex_handle Vertex_handle;
typedef CDT::Face_handle Face_handle;
typedef CDT::Point Point;


typedef std::pair<int, int>   Myedge;
typedef std::list<Myedge> List_edges;
typedef std::vector<Point> Vector_points;

int main()
{
  CDT cdt;

  // begin of reading .poly file

  int n_point=0;
  Vector_points con_points;
  std::vector<int> bd_flag;

  int n_con_edge=0;
  List_edges con_edges;

  int n_seeds;
  std::list<Point> seeds;

  int n_attri=0;
  Vector_points attri_points;
  std::vector<int> attri_flag;

  double x,y;
  Myedge e;
  int temp;

  std::cout<<"begin to read!"<<std::endl;

  std::ifstream input("squa_in_squa.poly",std::ios::in);

  input>>n_point>>temp>>temp>>temp;

  std::cout<<"n_point="<<n_point<<std::endl;


  for(int i=0;i<n_point;i++)
    {
      input>>temp>>x>>y>>temp;
      con_points.push_back(Point(x,y));
      std::cout<<x<<","<<y<<std::endl;
      bd_flag.push_back(temp);
    }

  std::cout<<"finished reading bounadary points!"<<std::endl;
 
  input>>n_con_edge>>temp;

 

  for(int i=0;i<n_con_edge;i++)
    {
      input>>temp>>e.first>>e.second>>temp;
      con_edges.push_back(e);
    }

  std::cout<<"n_con_edge="<<n_con_edge<<std::endl;
  input>>n_seeds;

  std::cout<<"n_seeds="<<n_seeds<<std::endl;

  if(n_seeds)
    {
      for(int i=0;i<n_seeds;i++)
    {
      input>>temp>>x>>y;
      seeds.push_back(Point(x,y));
    }
      input>>n_attri;
      if(n_attri)
    {
      for(int i=0;i<n_attri;i++)
        {
          input>>temp>>x>>y>>temp;
          attri_points.push_back(Point(x,y));
          attri_flag.push_back(temp);
        }
    }
    }
  input.close();

  // end of reading

  std::cout<<"computing the 2d box including the domain"<<std::endl;

  //computing the 2d box including the domain

  Vector_points::iterator left = CGAL::left_vertex_2(con_points.begin(),con_points.end(), K());
  Vector_points::iterator right = CGAL::right_vertex_2(con_points.begin(),con_points.end(),K());
  Vector_points::iterator top = CGAL::top_vertex_2(con_points.begin(),con_points.end(),K());
  Vector_points::iterator bottom = CGAL::bottom_vertex_2(con_points.begin(),con_points.end(),K());
  double w = (left->x() - right->x())/50.0;
  double h = (top->y() - bottom->y())/50.0;




  //the end of computing

  std::vector<Vertex_handle> Vhs;

 
  for(int i=0;i<n_point;i++)
    {
      Vertex_handle va=cdt.insert(con_points[i]);
      Vhs.push_back(va);

      std::cout<<"why!"<<"i="<<i<<std::endl;

      Vhs[i]->info().set_bd_flag(bd_flag[i]);
    }
 
  List_edges::iterator it;
  for(it = con_edges.begin();it!=con_edges.end();it++)
    {
      cdt.insert_constraint(Vhs[it->first-1],Vhs[it->second-1]);
    }


  std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl;

  std::cout << "Meshing the triangulation with default criterias..."
            << std::endl;

  Mesher mesher(cdt);
  if(n_seeds)
    {
      mesher.set_seeds(seeds.begin(),seeds.end());
      std::cout<<n_seeds<<std::endl;
    }

  mesher.set_criteria(Criteria(0.125, 0.5));
  mesher.refine_mesh();

  std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl;


   // Visualization

  CGAL::Geomview_stream gv(CGAL::Bbox_3(left->x()-w, bottom->y()-h, 0, right->x()+w, top->y()+h, 0));
  gv.set_line_width(4);
  gv.set_bg_color(CGAL::Color(0, 200, 200));

  std::cout << "Drawing 2D Delaunay triangulation in non-wired mode.n";
  gv.set_wired(true);
  gv << cdt;
  sleep(10);

  std::cout << "Enter a key to finish" << std::endl;
  char ch;
  std::cin >> ch;
  return 0;
}


https://blog.sciencenet.cn/blog-284809-361796.html

上一篇:留学准备
下一篇:我的Ubuntu 9.10 软件配置
收藏 IP: .*| 热度|

1 杨华磊

发表评论 评论 (0 个评论)

数据加载中...

Archiver|手机版|科学网 ( 京ICP备07017567号-12 )

GMT+8, 2024-4-25 09:33

Powered by ScienceNet.cn

Copyright © 2007- 中国科学报社

返回顶部