dealii-step-2

实例2是为了建立单元的自由度以及自由度的稀疏矩阵。
将自由度与单元、顶点、直线关联:

#include <deal.II/dofs/dof_handler.h>

对于平面四边形来说,双线性形函数的自由度只在单元顶点处,具体可以查看有限元形函数的内容。该类同样可以应用到一维和三维的情况:

#include <deal.II/fe/fe_q.h>

同时,还需要操纵自由度的工具:

#include <deal.II/dofs/dof_tools.h>

使用稀疏矩阵来存储自由度中的非零数值:

#include <deal.II/lac/sparse_matrix.h>

使用中间稀疏模式使非零元素尽量靠近对角线,减少存储消耗:

#include <deal.II/lac/dynamic_sparsity_pattern.h>

使用新的算法计算自由度:

#include <deal.II/dofs/dof_renumbering.h>

产生和加密网格:

void make_grid(Triangulation<2> &triangulation)
{
  const Point<2> center(1, 0);
  const double   inner_radius = 0.5, outer_radius = 1.0;
  GridGenerator::hyper_shell(
    triangulation, center, inner_radius, outer_radius, 5);

  for (unsigned int step = 0; step < 3; ++step)
    {
      for (auto &cell : triangulation.active_cell_iterators())
        for (unsigned int v = 0; v < GeometryInfo<2>::vertices_per_cell; ++v)
          {
            const double distance_from_center =
              center.distance(cell->vertex(v));

            if (std::fabs(distance_from_center - inner_radius) < 1e-10)
              {
                cell->set_refine_flag();
                break;
              }
          }

      triangulation.execute_coarsening_and_refinement();
    }
}

以上只是创建了一个网格,包含顶点位置及拓扑信息,还需要将自由度信息赋给顶点。使用类FE_Q来创建拉格朗日单元,需要给定多项式次数,1表示双线性单元。创建一个有限元对象,然后用DoFHandler分配自由度:

  const FE_Q<2> finite_element(1);
  dof_handler.distribute_dofs(finite_element);

将自由度分配到每个顶点之后,创建一个结构存储非0元素的位置。使用DynamicSparsityPattern类,传入的参数是自由度的大小:

  DynamicSparsityPattern dynamic_sparsity_pattern(dof_handler.n_dofs(),
                                                  dof_handler.n_dofs());

通过自由度分布给出非零元素所在的位置:

 DoFTools::make_sparsity_pattern(dof_handler, dynamic_sparsity_pattern);

然后将DynamicSparsityPattern的信息传回SpasityPattern,需要它进行计算:

  SparsityPattern sparsity_pattern;
  sparsity_pattern.copy_from(dynamic_sparsity_pattern);

最后存储到文件:

  std::ofstream out("sparsity_pattern1.svg");
  sparsity_pattern.print_svg(out);

对自由度进行编号

上面的方法得到的稀疏矩阵中非零元素离对角线较远,对于有些计算不够友好,可以通过重新编写自由度编号来改善,一般是同一个单元节点编号不要差太多,这里使用Cuthill_Mckee方法:

void renumber_dofs(DoFHandler<2> &dof_handler)
{
  DoFRenumbering::Cuthill_McKee(dof_handler);

  DynamicSparsityPattern dynamic_sparsity_pattern(dof_handler.n_dofs(),
                                                  dof_handler.n_dofs());
  DoFTools::make_sparsity_pattern(dof_handler, dynamic_sparsity_pattern);

  SparsityPattern sparsity_pattern;
  sparsity_pattern.copy_from(dynamic_sparsity_pattern);

  std::ofstream out("sparsity_pattern2.svg");
  sparsity_pattern.print_svg(out);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值