35#include "fourier_decomposed_helmholtz.h"
38#include "meshes/simple_rectangular_quadmesh.h"
41#include "oomph_crbond_bessel.h"
54template<
class ELEMENT>
66 const double& r_min,
const double& r_max,
67 const double& phi_min,
const double& phi_max) :
68 SimpleRectangularQuadMesh<ELEMENT>(n_r,n_phi,1.0,1.0)
77 unsigned n_node=this->nnode();
80 for (
unsigned n=0;n<n_node;n++)
83 Node* nod_pt=this->node_pt(n);
86 double x_old=nod_pt->x(0);
87 double y_old=nod_pt->x(1);
90 double r=r_min+(r_max-r_min)*x_old;
91 double phi=(phi_min+(phi_max-phi_min)*y_old)*
92 MathematicalConstants::Pi/180.0;
95 nod_pt->x(0)=r*cos(phi);
96 nod_pt->x(1)=r*sin(phi);
115 double K=3.0*MathematicalConstants::Pi;
118 std::complex<double>
I(0.0,1.0);
124 double R=sqrt(x[0]*x[0]+x[1]*x[1]);
127 theta=atan2(x[0],x[1]);
133 double bessel_offset=0.5;
140 double order_max_in=double(
N_terms-1)+bessel_offset;
141 double order_max_out=0;
152 CRBond_Bessel::bessjyv(order_max_in,
161 complex<double> u_ex(0.0,0.0);
162 for(
unsigned i=0;i<
N_terms;i++)
165 double p=Legendre_functions_helper::plgndr2(i,0,cos(theta));
168 u_ex+=(2.0*i+1.0)*pow(
I,i)*
169 sqrt(MathematicalConstants::Pi/(2.0*kr))*jv[i]*p;
186 ofstream some_file(
"planar_wave.dat");
188 for (
unsigned i_t=0;i_t<nt;i_t++)
190 double t=2.0*MathematicalConstants::Pi*double(i_t)/double(nt-1);
192 some_file <<
"ZONE I="<< nz <<
", J="<< nr << std::endl;
196 for (
unsigned i=0;i<nr;i++)
198 x[0]=0.001+double(i)/double(nr-1);
199 for (
unsigned j=0;j<nz;j++)
201 x[1]=double(j)/double(nz-1);
203 complex<double> uu=complex<double>(u[0],u[1])*exp(-
I*t);
204 some_file << x[0] <<
" " << x[1] <<
" "
205 << uu.real() <<
" " << uu.imag() <<
"\n";
240 std::complex<double>
I(0.0,1.0);
246 double R=sqrt(x[0]*x[0]+x[1]*x[1]);
249 theta=atan2(x[0],x[1]);
255 double bessel_offset=0.5;
262 double order_max_in=double(
N_terms-1)+bessel_offset;
263 double order_max_out=0;
274 CRBond_Bessel::bessjyv(order_max_in,
283 complex<double> u_ex(0.0,0.0);
287 double p=Legendre_functions_helper::plgndr2(i,
N_fourier,
290 u_ex+=
Coeff[i]*sqrt(MathematicalConstants::Pi/(2.0*kr))*(jv[i]+
I*yv[i])*p;
305 flux=std::complex<double>(0.0,0.0);
308 double R=sqrt(x[0]*x[0]+x[1]*x[1]);
311 theta=atan2(x[0],x[1]);
320 double bessel_offset=0.5;
327 double order_max_in=double(
N_terms-1)+bessel_offset;
328 double order_max_out=0;
339 CRBond_Bessel::bessjyv(order_max_in,
348 complex<double> u_ex(0.0,0.0);
352 double p=Legendre_functions_helper::plgndr2(i,
N_fourier,
355 flux-=
Coeff[i]*sqrt(MathematicalConstants::Pi/(2.0*kr))*p*
356 ( k*(djv[i]+
I*dyv[i]) - (0.5*(jv[i]+
I*yv[i])/R) );
378template<
class ELEMENT>
435template<
class ELEMENT>
449 double theta_min=-90.0;
450 double theta_max=90.0;
461 Helmholtz_outer_boundary_mesh_pt=
466 create_outer_bc_elements();
469 Helmholtz_inner_boundary_mesh_pt=
new Mesh;
470 create_flux_elements_on_inner_boundary();
481 unsigned n_element = Bulk_mesh_pt->nelement();
504template<
class ELEMENT>
510 Helmholtz_outer_boundary_mesh_pt->setup_gamma();
520 unsigned nel=Helmholtz_outer_boundary_mesh_pt->nelement();
521 for (
unsigned e=0;
e<
nel;
e++)
526 (Helmholtz_outer_boundary_mesh_pt->element_pt(
e));
529 const unsigned n_intpt =
el_pt->integral_pt()->nweight();
533 Helmholtz_outer_boundary_mesh_pt->gamma_at_gauss_point(
el_pt));
544 for(
unsigned i=0;
i<
n;
i++)
557 <<
flux.real() <<
" "
558 <<
flux.imag() <<
" "
573template<
class ELEMENT>
613 cout <<
"Norm of solution: " <<
sqrt(
norm) << std::endl << std::endl;
629 unsigned nn_element=Helmholtz_outer_boundary_mesh_pt->nelement();
634 Helmholtz_outer_boundary_mesh_pt->element_pt(
e));
643 <<
power << std::endl;
647 <<
power << std::endl;
657template<
class ELEMENT>
664 unsigned n_element = Bulk_mesh_pt->nboundary_element(
b);
669 Bulk_mesh_pt->boundary_element_pt(
b,
e));
672 int face_index = Bulk_mesh_pt->face_index_at_boundary(
b,
e);
695template<
class ELEMENT>
703 unsigned n_element = Bulk_mesh_pt->nboundary_element(
b);
708 Bulk_mesh_pt->boundary_element_pt(
b,
e));
711 int face_index = Bulk_mesh_pt->face_index_at_boundary(
b,
e);
799 for (
unsigned j=0;
j<=
n;
j++)
806 for (
unsigned j=0;
j<=
n;
j++)
813 for (
unsigned j=0;
j<=
n;
j++)
820 for (
unsigned j=0;
j<=
n;
j++)
847 for (
unsigned j=
n;
j<=5;
j++)
865 for (
unsigned j=0;
j<=3;
j++)
AnnularQuadMesh(const unsigned &n_r, const unsigned &n_phi, const double &r_min, const double &r_max, const double &phi_min, const double &phi_max)
~FourierDecomposedHelmholtzProblem()
Destructor (empty)
void create_outer_bc_elements()
Create BC elements on outer boundary.
Mesh * Helmholtz_inner_boundary_mesh_pt
Mesh of face elements that apply the prescribed flux on the inner boundary.
void actions_after_newton_solve()
Update the problem after solve (empty)
void create_flux_elements_on_inner_boundary()
Create flux elements on inner boundary.
void actions_before_newton_solve()
Update the problem specs before solve (empty)
void doc_solution(DocInfo &doc_info)
Doc the solution. DocInfo object stores flags/labels for where the output gets written to.
FourierDecomposedHelmholtzProblem()
Constructor.
FourierDecomposedHelmholtzDtNMesh< ELEMENT > * Helmholtz_outer_boundary_mesh_pt
Pointer to mesh containing the DtN boundary condition elements.
void check_gamma(DocInfo &doc_info)
Check gamma computation.
AnnularQuadMesh< ELEMENT > * Bulk_mesh_pt
Pointer to bulk mesh.
void actions_before_newton_convergence_check()
Recompute gamma integral before checking Newton residuals.
Namespace to test representation of planar wave in spherical polars.
void get_exact_u(const Vector< double > &x, Vector< double > &u)
Exact solution as a Vector of size 2, containing real and imag parts.
std::complex< double > I(0.0, 1.0)
Imaginary unit.
unsigned N_terms
Number of terms in series.
Namespace for the Fourier decomposed Helmholtz problem parameters.
unsigned El_multiplier
Multiplier for number of elements.
unsigned N_terms
Number of terms in the exact solution.
unsigned Nterms_for_DtN
Number of terms in computation of DtN boundary condition.
double K_squared
Square of the wavenumber.
void exact_minus_dudr(const Vector< double > &x, std::complex< double > &flux)
Get -du/dr (spherical r) for exact solution. Equal to prescribed flux on inner boundary.
int N_fourier
Fourier wave number.
Vector< double > Coeff(N_terms, 1.0)
Coefficients in the exact solution.
std::complex< double > I(0.0, 1.0)
Imaginary unit.
void get_exact_u(const Vector< double > &x, Vector< double > &u)
Exact solution as a Vector of size 2, containing real and imag parts.
int main(int argc, char **argv)
Driver code for Fourier decomposed Helmholtz problem.