42 #include "pml_helmholtz.h" 45 #include "meshes/triangle_mesh.h" 46 #include "meshes/rectangular_quadmesh.h" 48 using namespace oomph;
78 template<
class ELEMENT>
98 void doc_solution(DocInfo& doc_info);
101 void create_pml_meshes();
104 void apply_boundary_conditions();
109 void actions_before_adapt();
112 void actions_after_adapt();
168 template<
class ELEMENT>
173 Trace_file.open(
"RESLT/trace.dat");
179 Circle* inner_circle_pt=
new Circle(x_c,y_c,a);
183 TriangleMeshClosedCurve* outer_boundary_pt=0;
185 unsigned n_segments = 20;
186 Vector<TriangleMeshCurveSection*> outer_boundary_line_pt(4);
190 Vector<Vector<double> > vertex_coord(2);
191 for(
unsigned i=0;i<2;i++)
193 vertex_coord[i].resize(2);
197 vertex_coord[0][0]=-2.0;
198 vertex_coord[0][1]=-2.0;
199 vertex_coord[1][0]=-2.0;
200 vertex_coord[1][1]=2.0;
203 unsigned boundary_id=2;
204 outer_boundary_line_pt[0] =
new TriangleMeshPolyLine(vertex_coord,
208 vertex_coord[0][0]=-2.0;
209 vertex_coord[0][1]=2.0;
210 vertex_coord[1][0]=2.0;
211 vertex_coord[1][1]=2.0;
215 outer_boundary_line_pt[1] =
new TriangleMeshPolyLine(vertex_coord,
219 vertex_coord[0][0]=2.0;
220 vertex_coord[0][1]=2.0;
221 vertex_coord[1][0]=2.0;
222 vertex_coord[1][1]=-2.0;
226 outer_boundary_line_pt[2] =
new TriangleMeshPolyLine(vertex_coord,
230 vertex_coord[0][0]=2.0;
231 vertex_coord[0][1]=-2.0;
232 vertex_coord[1][0]=-2.0;
233 vertex_coord[1][1]=-2.0;
237 outer_boundary_line_pt[3] =
new TriangleMeshPolyLine(vertex_coord,
241 outer_boundary_pt =
new TriangleMeshPolygon(outer_boundary_line_pt);
245 Vector<TriangleMeshCurveSection*> inner_boundary_line_pt(2);
248 double s_start = 0.0;
249 double s_end = MathematicalConstants::Pi;
251 inner_boundary_line_pt[0]=
252 new TriangleMeshCurviLine(inner_circle_pt,
259 s_start = MathematicalConstants::Pi;
260 s_end = 2.0*MathematicalConstants::Pi;
262 inner_boundary_line_pt[1]=
263 new TriangleMeshCurviLine(inner_circle_pt,
272 Vector<TriangleMeshClosedCurve*> hole_pt(1);
273 Vector<double> hole_coords(2);
276 hole_pt[0]=
new TriangleMeshClosedCurve(inner_boundary_line_pt,
283 TriangleMeshParameters triangle_mesh_parameters(outer_boundary_pt);
286 triangle_mesh_parameters.internal_closed_curve_pt() = hole_pt;
289 triangle_mesh_parameters.element_area() = 0.1;
294 Bulk_mesh_pt=
new RefineableTriangleMesh<ELEMENT>(triangle_mesh_parameters);
297 Bulk_mesh_pt->spatial_error_estimator_pt()=
new Z2ErrorEstimator;
300 Bulk_mesh_pt->min_permitted_error()=0.00004;
301 Bulk_mesh_pt->max_permitted_error()=0.0001;
306 Bulk_mesh_pt=
new TriangleMesh<ELEMENT>(triangle_mesh_parameters);
311 add_sub_mesh(Bulk_mesh_pt);
320 this->mesh_pt()->output(
"global_mesh.dat");
321 this->mesh_pt()->output_boundaries(
"global_mesh_boundary.dat");
324 unsigned n_element = this->mesh_pt()->nelement();
325 for(
unsigned e=0;e<n_element;e++)
328 PMLHelmholtzEquations<2,AxisAlignedPMLElement<2>> *el_pt =
329 dynamic_cast<PMLHelmholtzEquations<2,AxisAlignedPMLElement<2>
>*>(
330 mesh_pt()->element_pt(e));
337 apply_boundary_conditions();
340 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
350 template<
class ELEMENT>
356 delete PML_right_mesh_pt;
358 delete PML_top_mesh_pt;
360 delete PML_left_mesh_pt;
362 delete PML_bottom_mesh_pt;
363 PML_bottom_mesh_pt=0;
364 delete PML_top_right_mesh_pt;
365 PML_top_right_mesh_pt=0;
366 delete PML_top_left_mesh_pt;
367 PML_top_left_mesh_pt=0;
368 delete PML_bottom_right_mesh_pt;
369 PML_bottom_right_mesh_pt=0;
370 delete PML_bottom_left_mesh_pt;
371 PML_bottom_left_mesh_pt=0;
378 add_sub_mesh(Bulk_mesh_pt);
382 rebuild_global_mesh();
390 template<
class ELEMENT>
398 rebuild_global_mesh();
404 unsigned n_element = this->mesh_pt()->nelement();
406 for(
unsigned e=0;e<n_element;e++)
409 PMLHelmholtzEquations<2,AxisAlignedPMLElement<2>> *el_pt =
410 dynamic_cast<PMLHelmholtzEquations<2,AxisAlignedPMLElement<2>
>*>(
411 mesh_pt()->element_pt(e));
418 apply_boundary_conditions();
427 template<
class ELEMENT>
433 unsigned n_bound = Bulk_mesh_pt->nboundary();
435 for(
unsigned b=0;b<n_bound;b++)
437 unsigned n_node = Bulk_mesh_pt->nboundary_node(b);
438 for (
unsigned n=0;n<n_node;n++)
440 if ((b==0) || (b==1))
442 Node* nod_pt=Bulk_mesh_pt->boundary_node_pt(b,n);
446 nod_pt->set_value(0,0.1);
447 nod_pt->set_value(1,0.0);
458 template<
class ELEMENT>
462 ofstream some_file,some_file2;
471 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
473 some_file.open(filename);
474 Bulk_mesh_pt->output(some_file,npts);
479 sprintf(filename,
"%s/coarse_soln%i.dat",doc_info.directory().c_str(),
481 some_file.open(filename);
482 unsigned npts_coarse=2;
483 Bulk_mesh_pt->output(some_file,npts_coarse);
489 sprintf(filename,
"%s/pml_soln%i.dat",doc_info.directory().c_str(),
491 some_file.open(filename);
492 PML_top_mesh_pt->output(some_file,npts);
493 PML_right_mesh_pt->output(some_file,npts);
494 PML_bottom_mesh_pt->output(some_file,npts);
495 PML_left_mesh_pt->output(some_file,npts);
496 PML_top_right_mesh_pt->output(some_file,npts);
497 PML_bottom_right_mesh_pt->output(some_file,npts);
498 PML_top_left_mesh_pt->output(some_file,npts);
499 PML_bottom_left_mesh_pt->output(some_file,npts);
507 Bulk_mesh_pt->compute_norm(norm);
508 Trace_file << norm << std::endl;
535 template<
class ELEMENT>
540 unsigned int left_boundary_id = 2;
543 unsigned int top_boundary_id = 3;
546 unsigned int right_boundary_id = 4;
549 unsigned int bottom_boundary_id = 5;
552 unsigned n_x_right_pml = 3;
555 unsigned n_y_top_pml = 3;
558 unsigned n_x_left_pml = 3;
561 unsigned n_y_bottom_pml = 3;
566 double width_x_right_pml = 0.2;
567 double width_y_top_pml = 0.2;
568 double width_x_left_pml = 0.2;
569 double width_y_bottom_pml = 0.2;
573 TwoDimensionalPMLHelper::create_right_pml_mesh
574 <EquivalentQElement<ELEMENT> >
575 (Bulk_mesh_pt,right_boundary_id,
576 n_x_right_pml, width_x_right_pml);
578 TwoDimensionalPMLHelper::create_top_pml_mesh
579 <EquivalentQElement<ELEMENT> >
580 (Bulk_mesh_pt, top_boundary_id,
581 n_y_top_pml, width_y_top_pml);
583 TwoDimensionalPMLHelper::create_left_pml_mesh
584 <EquivalentQElement<ELEMENT> >
585 (Bulk_mesh_pt, left_boundary_id,
586 n_x_left_pml, width_x_left_pml);
588 TwoDimensionalPMLHelper::create_bottom_pml_mesh
589 <EquivalentQElement<ELEMENT> >
590 (Bulk_mesh_pt, bottom_boundary_id,
591 n_y_bottom_pml, width_y_bottom_pml);
594 add_sub_mesh(PML_right_mesh_pt);
595 add_sub_mesh(PML_top_mesh_pt);
596 add_sub_mesh(PML_left_mesh_pt);
597 add_sub_mesh(PML_bottom_mesh_pt);
600 PML_top_right_mesh_pt =
601 TwoDimensionalPMLHelper::create_top_right_pml_mesh
602 <EquivalentQElement<ELEMENT> >
603 (PML_right_mesh_pt, PML_top_mesh_pt,
604 Bulk_mesh_pt, right_boundary_id);
606 PML_bottom_right_mesh_pt =
607 TwoDimensionalPMLHelper::create_bottom_right_pml_mesh
608 <EquivalentQElement<ELEMENT> >
609 (PML_right_mesh_pt, PML_bottom_mesh_pt,
610 Bulk_mesh_pt, right_boundary_id);
612 PML_top_left_mesh_pt =
613 TwoDimensionalPMLHelper::create_top_left_pml_mesh
614 <EquivalentQElement<ELEMENT> >
615 (PML_left_mesh_pt, PML_top_mesh_pt,
616 Bulk_mesh_pt, left_boundary_id);
618 PML_bottom_left_mesh_pt =
619 TwoDimensionalPMLHelper::create_bottom_left_pml_mesh
620 <EquivalentQElement<ELEMENT> >
621 (PML_left_mesh_pt, PML_bottom_mesh_pt,
622 Bulk_mesh_pt, left_boundary_id);
625 add_sub_mesh(PML_top_right_mesh_pt);
626 add_sub_mesh(PML_bottom_right_mesh_pt);
627 add_sub_mesh(PML_top_left_mesh_pt);
628 add_sub_mesh(PML_bottom_left_mesh_pt);
637 int main(
int argc,
char **argv)
642 CommandLineArgs::setup(argc,argv);
649 <TPMLHelmholtzElement<2,3, AxisAlignedPMLElement<2>> > > problem;
673 doc_info.set_directory(
"RESLT");
679 unsigned max_adapt=1;
683 problem.newton_solve(max_adapt);
688 problem.newton_solve();
double K_squared
Square of the wavenumber (also known as k^2)
void actions_before_newton_solve()
Update the problem specs before solve (empty)
void create_pml_meshes()
Create PML meshes.
Mesh * PML_bottom_mesh_pt
Pointer to the bottom PML mesh.
int main(int argc, char **argv)
Solve 2D Helmholtz problem.
double Wavenumber
Wavenumber (also known as k), k=omega/c.
Mesh * PML_right_mesh_pt
Pointer to the right PML mesh.
RefineableTriangleMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the refineable "bulk" mesh.
Namespace for the Helmholtz problem parameters.
~PMLProblem()
Destructor (empty)
void doc_solution(DocInfo &doc_info)
Doc the solution. DocInfo object stores flags/labels for where the output gets written to...
Mesh * PML_left_mesh_pt
Pointer to the left PML mesh.
Mesh * PML_top_right_mesh_pt
Pointer to the top right corner PML mesh.
void actions_after_adapt()
Actions after adapt: Rebuild the PML meshes.
void apply_boundary_conditions()
Apply boundary conditions.
Mesh * PML_bottom_right_mesh_pt
Pointer to the bottom right corner PML mesh.
ofstream Trace_file
Trace file.
Mesh * PML_top_left_mesh_pt
Pointer to the top left corner PML mesh.
void actions_after_newton_solve()
Update the problem specs after solve (empty)
void actions_before_adapt()
Actions before adapt: Wipe the PML meshes.
Mesh * PML_bottom_left_mesh_pt
Pointer to the bottom left corner PML mesh.
Mesh * PML_top_mesh_pt
Pointer to the top PML mesh.
TriangleMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the "bulk" mesh.