deal.II Step-2教程筆記

引言

用於枚舉基函數(形函數)的類稱爲DoFHandler。

要在網格上定義自由度,先要創建一個有限元對象,然後通過DoFHandler::distribute_dofs 函數傳給DoFHandler。(distribute DoFs 代表了枚舉基函數的過程。)DoFHandler 會提供總體裝配信息。

稀疏矩陣

DoFHandler 默認以隨機方式枚舉自由度,因此相應的稀疏矩陣也是隨機排列的。一般來說隨機性不影響求解,但某些預處理例如SSOR在特定排列下會更快些。

程序

網格庫

#include <deal.II/grid/tria.h>
#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/manifold_lib.h>

把自由度關聯到單元上的庫

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

描述雙線性單元(包括1至3維)的庫

#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>

輸出

#include <fstream>

命名空間

using namespace dealii;

網格生成

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();
    }
}

創建DoFHandler。首先要創建一個拉格朗日單元FE_Q,它的唯一參數表示多項式次數,雙線性爲1。接着把它傳給DoFHandler。

void distribute_dofs(DoFHandler<2> &dof_handler)
{
  const FE_Q<2> finite_element(1);
  dof_handler.distribute_dofs(finite_element);

然後考慮稀疏矩陣。存儲非零元素位置的類是SparsityPattern。這個類有一個毛病,必須先給定單行最大存儲數。二維時可以用DoFHandler::max_couplings_between_dofs()函數自動獲取,但三維時總是會過分估計。爲此我們可以用一個DynamicSparsityPattern,再複製到SparsityPattern裏。DynamicSparsityPattern 需要輸入矩陣大小。

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

用自由度填充DynamicSparsityPattern。

DoFTools::make_sparsity_pattern(dof_handler, dynamic_sparsity_pattern);

最後曲線救國,把位置信息複製到SparsityPattern。

SparsityPattern sparsity_pattern;
sparsity_pattern.copy_from(dynamic_sparsity_pattern);

把SparsityPattern輸出到圖片。

std::ofstream out("sparsity_pattern1.svg");
sparsity_pattern.print_svg(out);
發佈了23 篇原創文章 · 獲贊 5 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章