dealii-step-3

算例3介紹了泊松方程在dealii中的求解
泊松方程為邊界為0立磁,右端項(xiàng)非零,可以轉(zhuǎn)化為AU=F:
使用類Step3開始程序的運(yùn)行:

class Step3
{
public:
  Step3();
  void run();

使用一些私有對象完成對應(yīng)的功能:

private:
  void make_grid();
  void setup_system();
  void assemble_system();
  void solve();
  void output_results() const;

跟step-1一樣,定義網(wǎng)格節(jié)點(diǎn)變量:

  Triangulation<2> triangulation;
  FE_Q<2>          fe;
  DoFHandler<2>    dof_handler;

由拉普拉斯方程離散化得到的系統(tǒng)矩陣的稀疏模式和值的變量:

  SparsityPattern      sparsity_pattern;
  SparseMatrix<double> system_matrix;

方程右邊的解和變量:

  Vector<double> solution;
  Vector<double> system_rhs;

傳入類Step3中變量的值,默認(rèn)構(gòu)造函數(shù)會(huì)實(shí)現(xiàn)其他變量的值:

Step3::Step3()
  : fe(1)
  , dof_handler(triangulation)
{}

跟step-1一樣,產(chǎn)生網(wǎng)格信息:

void Step3::make_grid()
{
  GridGenerator::hyper_cube(triangulation, -1, 1);
  triangulation.refine_global(5);

  std::cout << "Number of active cells: " << triangulation.n_active_cells()
            << std::endl;
}

n_active_cells是指所有的網(wǎng)格沽瞭,包括已加密的和原先的父單元。
然后將動(dòng)態(tài)稀疏矩陣賦予sparsity_pattern中:

  DynamicSparsityPattern dsp(dof_handler.n_dofs());
  DoFTools::make_sparsity_pattern(dof_handler, dsp);
  sparsity_pattern.copy_from(dsp);

為了區(qū)別對待稀疏矩陣與矩陣,轉(zhuǎn)換稀疏矩陣為矩陣,這對于大規(guī)模計(jì)算非常重要:

  system_matrix.reinit(sparsity_pattern);

最后是設(shè)置方程右手邊的向量和解向量的大惺└摇:

  solution.reinit(dof_handler.n_dofs());
  system_rhs.reinit(dof_handler.n_dofs());

使用積分公式計(jì)算每個(gè)單元的積分:

  QGauss<2> quadrature_formula(fe.degree + 1);

需要每個(gè)單元的不同的形函數(shù)、倒數(shù)信息、雅可比行列式的權(quán)重:

  FEValues<2> fe_values(fe,
                        quadrature_formula,
                        update_values | update_gradients | update_JxW_values);

賦值一些常用的數(shù)值為變量僵娃,方便以后的重用以及更改,每個(gè)單元自由度個(gè)數(shù)以及求積分的點(diǎn)數(shù)目:

  const unsigned int dofs_per_cell = fe.dofs_per_cell;
  const unsigned int n_q_points    = quadrature_formula.size();

使用矩陣計(jì)算每個(gè)單元的單綱概作,最后再放到總綱的稀疏矩陣中,以及右邊的向量:

  FullMatrix<double> cell_matrix(dofs_per_cell, dofs_per_cell);
  Vector<double>     cell_rhs(dofs_per_cell);

使用局部編號(hào)來計(jì)算自由度,當(dāng)需要把局部單元自由度耦合到全局時(shí)默怨,需要知道該單元的全局編號(hào)讯榕,使用types::global_dof_index來定義一個(gè)臨時(shí)矩陣存儲(chǔ)該信息:

std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);

使用循環(huán)來遍歷全部單元,因?yàn)椴恍薷腸ell匙睹,可以把變量cell設(shè)為const:

  for (const auto &cell : dof_handler.active_cell_iterators())
    {

因?yàn)槊總€(gè)單元的雅克比的導(dǎo)數(shù)是不一樣的愚屁,所以在遍歷時(shí),需要重置變量cell,以及全局矩陣和右端項(xiàng):

      fe_values.reinit(cell);
      cell_matrix = 0;
      cell_rhs    = 0;

開始遍歷所有的積分點(diǎn)痕檬,由于每個(gè)積分點(diǎn)都與其他點(diǎn)有關(guān)霎槐,需要兩層循環(huán),使用i和j谆棺,使用shape_grid代表積分點(diǎn)處的形函數(shù)導(dǎo)數(shù)栽燕,JxW表示權(quán)重,對右端項(xiàng)做同樣的操作:

      for (unsigned int q_index = 0; q_index < n_q_points; ++q_index)
        {
          for (unsigned int i = 0; i < dofs_per_cell; ++i)
            for (unsigned int j = 0; j < dofs_per_cell; ++j)
              cell_matrix(i, j) +=
                (fe_values.shape_grad(i, q_index) * // grad phi_i(x_q)
                 fe_values.shape_grad(j, q_index) * // grad phi_j(x_q)
                 fe_values.JxW(q_index));           // dx

          for (unsigned int i = 0; i < dofs_per_cell; ++i)
            cell_rhs(i) += (fe_values.shape_value(i, q_index) * // phi_i(x_q)
                            1 *                                 // f(x_q)
                            fe_values.JxW(q_index));            // dx
        }

組總綱,需要單元自由度的總數(shù):

      cell->get_dof_indices(local_dof_indices);

遍歷所有的單元改淑,將單綱添加到總綱上:

      for (unsigned int i = 0; i < dofs_per_cell; ++i)
        for (unsigned int j = 0; j < dofs_per_cell; ++j)
          system_matrix.add(local_dof_indices[i],
                            local_dof_indices[j],
                            cell_matrix(i, j));
#右端項(xiàng)
      for (unsigned int i = 0; i < dofs_per_cell; ++i)
        system_rhs(local_dof_indices[i]) += cell_rhs(i);
    }

需要把約束或者說邊界條件加到方程中碍岔,否則方程有無數(shù)個(gè)解,首先獲得邊界的自由度和形函數(shù)朵夏,使用VectorTools::interpolate_boundary_values()插值邊界函數(shù)蔼啦,邊界有很多種形式,不同的問題邊界條件不一仰猖,需要單獨(dú)添加捏肢,使用Functions::ZeroFunction(處處為0的方程)定義VectorTools::interpolate_boundary_values(),使用std::map綁定總綱和邊界約束:

  std::map<types::global_dof_index, double> boundary_values;
  VectorTools::interpolate_boundary_values(dof_handler,
                                           0,
                                           Functions::ZeroFunction<2>(),
                                           boundary_values);
MatrixTools::apply_boundary_values(boundary_values,
                                     system_matrix,
                                     solution,
                                     system_rhs);
}

求解方程饥侵,收斂條件為運(yùn)行1000次或者殘差范數(shù)小于:10^12鸵赫,使用SolverCG模板求解,參數(shù)使用默認(rèn)躏升,CG求解器有一個(gè)前置調(diào)節(jié)器作為它的第四個(gè)參數(shù)辩棒。我們還沒有準(zhǔn)備好深入研究這個(gè)問題,所以我們使用PreconditionIdentity作為預(yù)處理:

void Step3::solve()
{
  SolverControl solver_control(1000, 1e-12);
SolverCG<Vector<double>> solver(solver_control);
  solver.solve(system_matrix, solution, system_rhs, PreconditionIdentity());
}

輸出結(jié)果膨疏,把數(shù)據(jù)dof_handler和solution傳遞給data_out一睁,把前端數(shù)據(jù)轉(zhuǎn)化為中間數(shù)據(jù)格式(后端數(shù)據(jù)),:

void Step3::output_results() const
{
  DataOut<2> data_out;
  data_out.attach_dof_handler(dof_handler);
  data_out.add_data_vector(solution, "solution");
  data_out.build_patches();
#寫入數(shù)據(jù)
  std::ofstream output("solution.vtk");
  data_out.write_vtk(output);
}

調(diào)用類Step3中的其他函數(shù)運(yùn)行:

void Step3::run()
{
  make_grid();
  setup_system();
  assemble_system();
  solve();
  output_results();
}

主函數(shù):

int main()
{
  deallog.depth_console(2);
  Step3 laplace_problem;
  laplace_problem.run();

  return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末佃却,一起剝皮案震驚了整個(gè)濱河市者吁,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌饲帅,老刑警劉巖复凳,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瘤泪,死亡現(xiàn)場離奇詭異,居然都是意外死亡染坯,警方通過查閱死者的電腦和手機(jī)均芽,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來单鹿,“玉大人,你說我怎么就攤上這事深纲≈俪” “怎么了?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵湃鹊,是天一觀的道長儒喊。 經(jīng)常有香客問我,道長币呵,這世上最難降的妖魔是什么怀愧? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮余赢,結(jié)果婚禮上芯义,老公的妹妹穿的比我還像新娘。我一直安慰自己妻柒,他們只是感情好扛拨,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著举塔,像睡著了一般绑警。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上央渣,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天计盒,我揣著相機(jī)與錄音,去河邊找鬼芽丹。 笑死北启,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的志衍。 我是一名探鬼主播暖庄,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼楼肪!你這毒婦竟也來了培廓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤春叫,失蹤者是張志新(化名)和其女友劉穎肩钠,沒想到半個(gè)月后泣港,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體小泉,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仑嗅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年揖盘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了严就。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邀层。...
    茶點(diǎn)故事閱讀 39,919評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡势就,死狀恐怖最域,靈堂內(nèi)的尸體忽然破棺而出咒程,到底是詐尸還是另有隱情洋腮,我是刑警寧澤箫柳,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站啥供,受9級(jí)特大地震影響悯恍,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜伙狐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一涮毫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贷屎,春花似錦罢防、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至美旧,卻和暖如春渤滞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背榴嗅。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工妄呕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嗽测。 一個(gè)月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓绪励,卻偏偏與公主長得像,于是被迫代替她去往敵國和親唠粥。 傳聞我的和親對象是個(gè)殘疾皇子疏魏,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 本系列教程來源于出版設(shè)計(jì)《基于MATLAB編程基礎(chǔ)與典型應(yīng)用書籍》,如涉及版權(quán)問題晤愧,請聯(lián)系:156204968@q...
    德特?cái)?shù)據(jù)閱讀 1,622評論 0 1
  • 研究溫度場計(jì)算的相關(guān)理論知識(shí)大莫,主要是通過研究電器產(chǎn)品的數(shù)學(xué)建模過程,得到PDE和它的邊界條件官份,即構(gòu)成一個(gè)定解問題只厘,...
    QzLancer閱讀 6,497評論 0 2
  • 考試科目:高等數(shù)學(xué)烙丛、線性代數(shù)、概率論與數(shù)理統(tǒng)計(jì) 考試形式和試卷結(jié)構(gòu) 一羔味、試卷滿分及考試時(shí)間 試卷滿分為150分河咽,考...
    Saudade_lh閱讀 1,077評論 0 0
  • 2017年考研數(shù)學(xué)一大綱原文 考試科目:高等數(shù)學(xué)、線性代數(shù)赋元、概率論與數(shù)理統(tǒng)計(jì) 考試形式和試卷結(jié)構(gòu) 一忘蟹、試卷滿分及考...
    SheBang_閱讀 624評論 0 7
  • 考試形式和試卷結(jié)構(gòu)一、試卷滿分及考試時(shí)間 試卷滿分為150分们陆,考試時(shí)間為180分鐘 二寒瓦、答題方式 答題方式為閉卷、...
    幻無名閱讀 754評論 0 3