Poisson問題の完全な例

次の例は,テストプログラム tests/laplacian_with_bricks.cc の一部です.メッシュおよび有限要素法の構成は省略されています.メッシュが構築され,このメッシュに mf_umf_rhs という2つの有限要素法が構築されていると仮定します. NEUMANN_BOUNDARY_NUMDIRICHLET_BOUNDARY_NUM は,そのメッシュ上の2つの有効な境界指標であるとも仮定されています.コードは,ソース項,Neumann条件,Dirichlet条件のデータを構築するために, mf_rhs で補間される3つの関数の定義から始まります.modelオブジェクトの宣言,要素の追加,および問題の解の計算は次の通りです.

using bgeot::base_small_vector;
// Exact solution. Allows an interpolation for the Dirichlet condition.
scalar_type sol_u(const base_node &x) { return sin(x[0]+x[1]); }
// Right hand side. Allows an interpolation for the source term.
scalar_type sol_f(const base_node &x) { return 2*sin(x[0]+x[1]); }
// Gradient of the solution. Allows an interpolation for the Neumann term.
base_small_vector sol_grad(const base_node &x)
{ return base_small_vector(cos(x[0]+x[1]), cos(x[0]+x[1]); }

int main(void) {

  // ... definition of a mesh
  // ... definition of a finite element method mf_u
  // ... definition of a finite element method mf_rhs
  // ... definition of an integration method mim
  // ... definition of boundaries NEUMANN_BOUNDARY_NUM
  //                        and DIRICHLET_BOUNDARY_NUM

  // Model object
  getfem::model laplacian_model;

  // Main unknown of the problem
  laplacian_model.add_fem_variable("u", mf_u);

  // Laplacian term on u.
  getfem::add_Laplacian_brick(laplacian_model, mim, "u");

  // Volumic source term.
  std::vector<scalar_type> F(mf_rhs.nb_dof());
  getfem::interpolation_function(mf_rhs, F, sol_f);
  laplacian_model.add_initialized_fem_data("VolumicData", mf_rhs, F);
  getfem::add_source_term_brick(laplacian_model, mim, "u", "VolumicData");

  // Neumann condition.
  gmm::resize(F, mf_rhs.nb_dof()*N);
  getfem::interpolation_function(mf_rhs, F, sol_grad);
  laplacian_model.add_initialized_fem_data("NeumannData", mf_rhs, F);
  getfem::add_normal_source_term_brick
  (laplacian_model, mim, "u", "NeumannData", NEUMANN_BOUNDARY_NUM);

  // Dirichlet condition.
  gmm::resize(F, mf_rhs.nb_dof());
  getfem::interpolation_function(mf_rhs, F, sol_u);
  laplacian_model.add_initialized_fem_data("DirichletData", mf_rhs, F);
  getfem::add_Dirichlet_condition_with_multipliers
  (laplacian_model, mim, "u", mf_u, DIRICHLET_BOUNDARY_NUM, "DirichletData");

  gmm::iteration iter(residual, 1, 40000);
  getfem::standard_solve(laplacian_model, iter);

  std::vector<scalar_type> U(mf_u.nb_dof());
  gmm::copy(laplacian_model.real_variable("u"), U);

  // ... doing something with the solution ...

  return 0;
}

ブリック要素は任意の次数で追加できます.