45 namespace Legendre_functions_helper
61 double plgndr1(
const unsigned& n,
const double& x)
69 if (std::fabs(x) > 1.0)
71 std::ostringstream error_stream;
72 error_stream <<
"Bad arguments in routine plgndr1: x=" << x
73 <<
" but should be less than 1 in absolute value.\n";
74 throw OomphLibError(error_stream.str(),
75 OOMPH_CURRENT_FUNCTION,
76 OOMPH_EXCEPTION_LOCATION);
96 pmm2=(x*(2*i-1)*pmm1-(i-1)*pmm)/i;
110 double plgndr2(
const unsigned& l,
const unsigned& m,
const double& x)
113 double fact,pmm,pmmp1,somx2;
118 if (std::fabs(x) > 1.0)
120 std::ostringstream error_stream;
121 error_stream <<
"Bad arguments in routine plgndr2: x=" << x
122 <<
" but should be less than 1 in absolute value.\n";
123 throw OomphLibError(error_stream.str(),
124 OOMPH_CURRENT_FUNCTION,
125 OOMPH_EXCEPTION_LOCATION);
139 somx2=sqrt((1.0-x)*(1.0+x));
147 if (l == m)
return pmm;
160 for (ll=m+2;ll<=l;ll++)
162 pll=(x*(2*ll-1)*pmmp1-(ll+m-1)*pmm)/(ll-m);
184 template<
unsigned NNODE_1D,
class PML_ELEMENT>
185 const unsigned QPMLFourierDecomposedHelmholtzElement<NNODE_1D,PML_ELEMENT>::
189 double PMLFourierDecomposedHelmholtzEquationsBase::
190 Default_Physical_Constant_Value = 0.0;
200 template<
class PML_ELEMENT>
205 const unsigned& flag)
208 const unsigned n_node = nnode();
211 Shape psi(n_node), test(n_node);
212 DShape dpsidx(n_node,2), dtestdx(n_node,2);
215 const unsigned n_intpt = integral_pt()->nweight();
218 int local_eqn_real=0, local_unknown_real=0;
219 int local_eqn_imag=0, local_unknown_imag=0;
222 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
225 double w = integral_pt()->weight(ipt);
229 this->dshape_and_dtest_eulerian_at_knot_pml_fourier_decomposed_helmholtz
230 (ipt,psi,dpsidx,test,dtestdx);
237 std::complex<double> interpolated_u(0.0,0.0);
244 for(
unsigned l=0;l<n_node;l++)
247 for(
unsigned j=0;j<2;j++)
249 interpolated_x[j] += this->raw_nodal_position(l,j)*psi(l);
253 const std::complex<double> u_value(
254 this->raw_nodal_value
255 (l,this->u_index_pml_fourier_decomposed_helmholtz().real()),
256 this->raw_nodal_value
257 (l,this->u_index_pml_fourier_decomposed_helmholtz().imag()));
260 interpolated_u += u_value*psi(l);
263 for(
unsigned j=0;j<2;j++)
265 interpolated_dudx[j] += u_value*dpsidx(l,j);
271 std::complex<double> source(0.0,0.0);
272 this->get_source_pml_fourier_decomposed_helmholtz
273 (ipt,interpolated_x,source);
275 double n = (double)pml_fourier_wavenumber();
276 double n_squared = n*n;
279 std::complex<double> pml_k_squared_factor = std::complex<double>(1.0,0.0);
289 this->pml_transformation_jacobian(ipt, s, interpolated_x, pml_jacobian,
293 this->compute_laplace_matrix_and_det(pml_jacobian, laplace_matrix,
294 pml_k_squared_factor);
300 std::complex<double> complex_r = transformed_x[0];
304 std::complex<double> pml_k_squared_jacobian =
305 - pml_k_squared_factor * ( k_squared() - n_squared / (complex_r * complex_r))
310 for (
unsigned k=0;k<2;k++)
312 pml_laplace_jacobian[k] = laplace_matrix(k,k)* complex_r *
W;
318 std::complex<double> pml_k_squared_residual = pml_k_squared_jacobian
323 for (
unsigned k=0;k<2;k++)
325 pml_laplace_residual[k] = pml_laplace_jacobian[k] * interpolated_dudx[k];
331 for(
unsigned l=0;l<n_node;l++)
336 (l,u_index_pml_fourier_decomposed_helmholtz().real());
339 (l,u_index_pml_fourier_decomposed_helmholtz().imag());
345 if(local_eqn_real >= 0)
348 residuals[local_eqn_real] += pml_k_squared_residual.real()*test(l);
351 for (
unsigned k=0;k<2;k++)
353 residuals[local_eqn_real]+=pml_laplace_residual[k].real()*dtestdx(l,k);
361 for(
unsigned l2=0;l2<n_node;l2++)
366 (l2,u_index_pml_fourier_decomposed_helmholtz().real());
369 (l2,u_index_pml_fourier_decomposed_helmholtz().imag());
372 if(local_unknown_real >= 0)
375 jacobian(local_eqn_real,local_unknown_real) +=
376 pml_k_squared_jacobian.real() * psi(l2)*test(l);
379 for (
unsigned k=0;k<2;k++)
381 jacobian(local_eqn_real,local_unknown_real) +=
382 pml_laplace_jacobian[k].real()*dpsidx(l2,k)*dtestdx(l,k);
386 if(local_unknown_imag >= 0)
389 jacobian(local_eqn_real,local_unknown_imag) +=
390 - pml_k_squared_jacobian.imag()*psi(l2)*test(l);
393 for (
unsigned k=0;k<2;k++)
395 jacobian(local_eqn_real,local_unknown_imag) +=
396 - pml_laplace_jacobian[k].imag()*dpsidx(l2,k)*dtestdx(l,k);
408 if(local_eqn_imag >= 0)
411 residuals[local_eqn_imag] += pml_k_squared_residual.imag()*test(l);
414 for (
unsigned k=0;k<2;k++)
416 residuals[local_eqn_imag]+=pml_laplace_residual[k].imag()*dtestdx(l,k);
424 for(
unsigned l2=0;l2<n_node;l2++)
426 local_unknown_imag = nodal_local_eqn
427 (l2,u_index_pml_fourier_decomposed_helmholtz().imag());
430 (l2,u_index_pml_fourier_decomposed_helmholtz().real());
433 if(local_unknown_imag >= 0)
436 jacobian(local_eqn_imag,local_unknown_imag) +=
437 pml_k_squared_jacobian.real()*psi(l2)*test(l);
440 for (
unsigned k=0;k<2;k++)
442 jacobian(local_eqn_imag,local_unknown_imag) +=
443 pml_laplace_jacobian[k].real()*dpsidx(l2,k)*dtestdx(l,k);
447 if(local_unknown_real >= 0)
450 jacobian(local_eqn_imag,local_unknown_real) +=
451 pml_k_squared_jacobian.imag()*psi(l2)*test(l);
454 for (
unsigned k=0;k<2;k++)
456 jacobian(local_eqn_imag,local_unknown_real) +=
457 pml_laplace_jacobian[k].imag()*dpsidx(l2,k)*dtestdx(l,k);
507 (std::ostream &outfile,
508 const unsigned &nplot)
515 outfile << tecplot_zone_string(nplot);
518 unsigned num_plot_points=nplot_points(nplot);
519 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
523 get_s_plot(iplot,nplot,s);
525 u(interpolated_u_pml_fourier_decomposed_helmholtz(s));
526 for(
unsigned i=0;i<2;i++)
528 outfile << interpolated_x(s,i) <<
" ";
530 outfile << u.real() <<
" " << u.imag() << std::endl;
535 write_tecplot_zone_footer(outfile,nplot);
554 (std::ostream &outfile,
556 const unsigned &nplot)
562 outfile << tecplot_zone_string(nplot);
565 unsigned num_plot_points=nplot_points(nplot);
566 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
570 get_s_plot(iplot,nplot,s);
572 u(interpolated_u_pml_fourier_decomposed_helmholtz(s));
573 for(
unsigned i=0;i<2;i++)
575 outfile << interpolated_x(s,i) <<
" ";
577 outfile << u.real()*cos(phi)+u.imag()*sin(phi) << std::endl;
582 write_tecplot_zone_footer(outfile,nplot);
595 const unsigned &nplot)
601 fprintf(file_pt,
"%s",tecplot_zone_string(nplot).c_str());
604 unsigned num_plot_points=nplot_points(nplot);
605 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
608 get_s_plot(iplot,nplot,s);
610 u(interpolated_u_pml_fourier_decomposed_helmholtz(s));
612 for(
unsigned i=0;i<2;i++)
614 fprintf(file_pt,
"%g ",interpolated_x(s,i));
617 for(
unsigned i=0;i<2;i++)
619 fprintf(file_pt,
"%g ",interpolated_x(s,i));
621 fprintf(file_pt,
"%g ",u.real());
622 fprintf(file_pt,
"%g \n",u.imag());
627 write_tecplot_zone_footer(file_pt,nplot);
641 std::ostream &outfile,
642 const unsigned &nplot,
652 outfile << tecplot_zone_string(nplot);
658 unsigned num_plot_points=nplot_points(nplot);
659 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
662 get_s_plot(iplot,nplot,s);
668 (*exact_soln_pt)(x,exact_soln);
671 for(
unsigned i=0;i<2;i++)
673 outfile << x[
i] <<
" ";
675 outfile << exact_soln[0] <<
" " << exact_soln[1] << std::endl;
679 write_tecplot_zone_footer(outfile,nplot);
696 std::ostream &outfile,
698 const unsigned &nplot,
708 outfile << tecplot_zone_string(nplot);
714 unsigned num_plot_points=nplot_points(nplot);
715 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
718 get_s_plot(iplot,nplot,s);
724 (*exact_soln_pt)(x,exact_soln);
727 for(
unsigned i=0;i<2;i++)
729 outfile << x[
i] <<
" ";
731 outfile << exact_soln[0]*cos(phi)+ exact_soln[1]*sin(phi) << std::endl;
735 write_tecplot_zone_footer(outfile,nplot);
749 std::ostream &outfile,
751 double& error,
double& norm)
765 unsigned n_node = nnode();
770 unsigned n_intpt = integral_pt()->nweight();
773 outfile <<
"ZONE" << std::endl;
779 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
783 for(
unsigned i=0;i<2;i++)
785 s[
i] = integral_pt()->knot(ipt,i);
789 double w = integral_pt()->weight(ipt);
792 double J=J_eulerian(s);
801 std::complex<double> u_fe=
802 interpolated_u_pml_fourier_decomposed_helmholtz(s);
805 (*exact_soln_pt)(x,exact_soln);
808 for(
unsigned i=0;i<2;i++)
810 outfile << x[
i] <<
" ";
812 outfile << exact_soln[0] <<
" " << exact_soln[1] <<
" " 813 << exact_soln[0]-u_fe.real() <<
" " << exact_soln[1]-u_fe.imag()
817 norm+=(exact_soln[0]*exact_soln[0]+exact_soln[1]*exact_soln[1])*W;
818 error+=( (exact_soln[0]-u_fe.real())*(exact_soln[0]-u_fe.real())+
819 (exact_soln[1]-u_fe.imag())*(exact_soln[1]-u_fe.imag()) )*
W;
843 unsigned n_node = nnode();
848 unsigned n_intpt = integral_pt()->nweight();
851 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
855 for(
unsigned i=0;i<2;i++)
857 s[
i] = integral_pt()->knot(ipt,i);
861 double w = integral_pt()->weight(ipt);
864 double J=J_eulerian(s);
870 std::complex<double> u_fe=
871 interpolated_u_pml_fourier_decomposed_helmholtz(s);
874 norm+=(u_fe.real()*u_fe.real()+u_fe.imag()*u_fe.imag())*W;
887 template<
class PML_ELEMENT>
double factorial(const unsigned &l)
Factorial.
void compute_norm(double &norm)
Compute norm of fe solution.
void output_real_fct(std::ostream &outfile, const double &phi, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output function for real part of full time-dependent fct u = Re( (u_r +i u_i) exp(-i omega t) at phas...
virtual void fill_in_generic_residual_contribution_pml_fourier_decomposed_helmholtz(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Compute element residual Vector only (if flag=and/or element Jacobian matrix.
virtual unsigned self_test()
Self-test: Check inversion of element & do self-test for GeneralisedElement. Return 0 if OK...
double plgndr1(const unsigned &n, const double &x)
Legendre polynomials depending on one parameter.
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as ...
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Get error against and norm of exact solution.
unsigned self_test()
Self-test: Return 0 for OK.
void output_real(std::ostream &outfile, const double &phi, const unsigned &n_plot)
Output function for real part of full time-dependent solution u = Re( (u_r +i u_i) exp(-i omega t) at...
void output(std::ostream &outfile)
Output with default number of plot points.
double plgndr2(const unsigned &l, const unsigned &m, const double &x)
Legendre polynomials depending on two parameters.