37 using std::endl;
using std::cout;
using std::cerr;
38 using std::ends;
using std::cin;
43 using bgeot::scalar_type;
44 using bgeot::complex_type;
47 using bgeot::base_matrix;
52 typedef getfem::modeling_standard_complex_sparse_matrix sparse_matrix;
53 typedef getfem::modeling_standard_complex_plain_vector plain_vector;
58 struct Helmholtz_problem {
60 enum { DIRICHLET_BOUNDARY_NUM = 0, ROBIN_BOUNDARY_NUM = 1};
65 complex_type wave_number;
70 std::string datafilename;
71 bgeot::md_param PARAM;
73 bool solve(plain_vector &U);
75 void compute_error(plain_vector &U);
76 Helmholtz_problem(
void) : mim(mesh), mf_u(mesh), mf_rhs(mesh) {}
79 complex_type __wave_number;
81 complex_type incoming_field(
const base_node &P) {
82 return complex_type(cos(__wave_number.real()*P[1]+.2),
83 sin(__wave_number.real()*P[1]+.2));
94 void Helmholtz_problem::init(
void) {
95 std::string FEM_TYPE = PARAM.string_value(
"FEM_TYPE",
"FEM name");
96 std::string INTEGRATION = PARAM.string_value(
"INTEGRATION",
97 "Name of integration method");
98 cout <<
"FEM_TYPE=" << FEM_TYPE <<
"\n";
99 cout <<
"INTEGRATION=" << INTEGRATION <<
"\n";
102 size_type Nt = PARAM.int_value(
"NTHETA",
"Nomber of space steps "),
103 Nr=PARAM.int_value(
"NR",
"Nomber of space steps ");
104 size_type gt_order = PARAM.int_value(
"GTDEGREE",
105 "polynomial degree of geometric transformation");
106 scalar_type dtheta=2*M_PI*1./scalar_type(Nt);
107 scalar_type R0 = PARAM.real_value(
"R0",
"R0");
108 scalar_type R1 = PARAM.real_value(
"R1",
"R1");
109 scalar_type dR = (R1-R0)/scalar_type(Nr-1);
111 pgt = bgeot::parallelepiped_geotrans(2,
short_type(gt_order));
114 std::vector<size_type> ipts; ipts.reserve(gmm::sqr(gt_order+1));
115 for (
size_type ii=0; ii <= gt_order; ++ii) {
116 for (
size_type jj=0; jj <= gt_order; ++jj) {
117 scalar_type r = R0 + scalar_type(j)*dR
118 + scalar_type(jj)*(dR/scalar_type(gt_order));
119 scalar_type t = scalar_type(i)*dtheta
120 + scalar_type(ii)*dtheta/scalar_type(gt_order);
121 ipts.push_back(mesh.add_point(base_node(r*cos(t),r*sin(t))));
124 mesh.add_convex(pgt, ipts.begin());
128 datafilename = PARAM.string_value(
"ROOTFILENAME",
"Base name of data files.");
129 residual = PARAM.real_value(
"RESIDUAL");
if (residual == 0.) residual = 1e-10;
131 __wave_number = wave_number = complex_type
132 (PARAM.real_value(
"WAVENUM_R",
"Real part of the wave number"),
133 PARAM.real_value(
"WAVENUM_I",
"Imaginary part of the wave number"));
135 with_mult = int(PARAM.int_value(
"DIRICHLET_VERSION",
136 "Dirichlet condition version"));
141 getfem::pintegration_method ppi =
144 mim.set_integration_method(ppi);
145 mf_u.set_finite_element(pf_u);
149 std::string data_fem_name = PARAM.string_value(
"DATA_FEM_TYPE");
150 if (data_fem_name.size() == 0) {
151 GMM_ASSERT1(pf_u->is_lagrange(),
"You are using a non-lagrange FEM. " 152 <<
"In that case you need to set " 153 <<
"DATA_FEM_TYPE in the .param file");
154 mf_rhs.set_finite_element(pf_u);
161 cout <<
"Selecting Robin and Dirichlet boundaries\n";
166 if (gmm::vect_norm2(mesh.points_of_face_of_convex(i.cv(),
168 mesh.region(ROBIN_BOUNDARY_NUM).add(i.cv(),i.f());
169 }
else mesh.region(DIRICHLET_BOUNDARY_NUM).add(i.cv(),i.f());
178 bool Helmholtz_problem::solve(plain_vector &U) {
184 Helmholtz_model.add_fem_variable(
"u", mf_u);
187 plain_vector K(1); K[0] = wave_number;
188 Helmholtz_model.add_initialized_fixed_size_data(
"k", K);
192 plain_vector Q(1); Q[0] = wave_number * complex_type(0,1.);
193 Helmholtz_model.add_initialized_fixed_size_data(
"Q", Q);
197 plain_vector F(mf_rhs.nb_dof());
199 Helmholtz_model.add_initialized_fem_data(
"DirichletData", mf_rhs, F);
201 (Helmholtz_model, mim,
"u", mf_u,
202 DIRICHLET_BOUNDARY_NUM,
"DirichletData");
210 gmm::copy(Helmholtz_model.complex_variable(
"u"), U);
214 return (iter.converged());
221 int main(
int argc,
char *argv[]) {
223 GMM_SET_EXCEPTION_DEBUG;
227 p.PARAM.read_command_line(argc, argv);
229 plain_vector U(p.mf_u.nb_dof());
230 if (!p.solve(U)) GMM_ASSERT1(
false,
"Solve has failed");
232 if (p.PARAM.int_value(
"VTK_EXPORT")) {
233 cout <<
"export to " << p.datafilename +
".vtk" <<
"..\n";
235 p.PARAM.int_value(
"VTK_EXPORT")==1);
238 exp.write_point_data(p.mf_u, gmm::real_part(U),
"helmholtz_rfield");
239 exp.write_point_data(p.mf_u, gmm::imag_part(U),
"helmholtz_ifield");
240 cout <<
"export done, you can view the data file with (for example)\n" 241 "mayavi2 -d helmholtz.vtk -f WarpScalar -m Surface -m Outline" structure used to hold a set of convexes and/or convex faces.
Export solutions to various formats.
void interpolation_function(mesh_fem &mf_target, const VECT &VV, F &f, mesh_region rg=mesh_region::all_convexes())
interpolation of a function f on mf_target.
pfem fem_descriptor(const std::string &name)
get a fem descriptor from its string name.
The Iteration object calculates whether the solution has reached the desired accuracy, or whether the maximum number of iterations has been reached.
size_type APIDECL add_Helmholtz_brick(model &md, const mesh_im &mim, const std::string &varname, const std::string &dataexpr, size_type region=size_type(-1))
Add a Helmoltz brick to the model.
Describe a mesh (collection of convexes (elements) and points).
void standard_solve(model &md, gmm::iteration &iter, rmodel_plsolver_type lsolver, abstract_newton_line_search &ls)
A default solver for the model brick system.
pintegration_method int_method_descriptor(std::string name, bool throw_if_not_found=true)
Get an integration method from its name .
Describe an integration method linked to a mesh.
``Model'' variables store the variables, the data and the description of a model. ...
size_t size_type
used as the common size type in the library
Standard solvers for model bricks.
"iterator" class for regions.
The output of a getfem::mesh_slicer which has been recorded.
sparse vector built upon std::vector.
std::shared_ptr< const getfem::virtual_fem > pfem
type of pointer on a fem description
Describe a finite element method linked to a mesh.
gmm::uint16_type short_type
used as the common short type integer in the library
Include common gmm files.
size_type APIDECL add_Fourier_Robin_brick(model &md, const mesh_im &mim, const std::string &varname, const std::string &dataexpr, size_type region)
Add a Fourier-Robin brick to the model.
Miscelleanous assembly routines for common terms. Use the low-level generic assembly. Prefer the high-level one.
void resize(M &v, size_type m, size_type n)
*/
std::shared_ptr< const bgeot::geometric_trans > pgeometric_trans
pointer type for a geometric transformation
size_type APIDECL add_Dirichlet_condition_with_multipliers(model &md, const mesh_im &mim, const std::string &varname, const std::string &multname, size_type region, const std::string &dataname=std::string())
Add a Dirichlet condition on the variable varname and the mesh region region.
void APIDECL outer_faces_of_mesh(const mesh &m, const dal::bit_vector &cvlst, convex_face_ct &flist)
returns a list of "exterior" faces of a mesh (i.e.