Poisson問題の完全な例¶
次の例は,テストプログラム tests/laplacian_with_bricks.cc
の一部です.メッシュおよび有限要素法の構成は省略されています.メッシュが構築され,このメッシュに mf_u
と mf_rhs
という2つの有限要素法が構築されていると仮定します. NEUMANN_BOUNDARY_NUM
と DIRICHLET_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;
}
ブリック要素は任意の次数で追加できます.