36 template<
unsigned DIM,
unsigned NNODE_1D>
41 template<
unsigned DIM>
54 template<
unsigned DIM>
62 const unsigned n_node = nnode();
65 Shape psi(n_node), test(n_node);
66 DShape dpsidx(n_node, DIM), dtestdx(n_node, DIM);
69 const unsigned n_intpt = integral_pt()->nweight();
72 int local_eqn_real = 0, local_unknown_real = 0;
73 int local_eqn_imag = 0, local_unknown_imag = 0;
76 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
79 double w = integral_pt()->weight(ipt);
82 double J = dshape_and_dtest_eulerian_at_knot_helmholtz(
83 ipt, psi, dpsidx, test, dtestdx);
90 std::complex<double> interpolated_u(0.0, 0.0);
97 for (
unsigned l = 0; l < n_node; l++)
100 for (
unsigned j = 0; j < DIM; j++)
102 interpolated_x[j] += raw_nodal_position(l, j) * psi(l);
106 const std::complex<double> u_value(
107 raw_nodal_value(l, u_index_helmholtz().real()),
108 raw_nodal_value(l, u_index_helmholtz().imag()));
111 interpolated_u += u_value * psi(l);
114 for (
unsigned j = 0; j < DIM; j++)
116 interpolated_dudx[j] += u_value * dpsidx(l, j);
122 std::complex<double> source(0.0, 0.0);
123 get_source_helmholtz(ipt, interpolated_x, source);
129 std::complex<double> pml_k_squared_factor =
130 std::complex<double>(1.0, 0.0);
137 compute_pml_coefficients(
138 ipt, interpolated_x, pml_laplace_factor, pml_k_squared_factor);
141 std::complex<double> alpha_pml_k_squared_factor = std::complex<double>(
142 pml_k_squared_factor.real() - alpha() * pml_k_squared_factor.imag(),
143 alpha() * pml_k_squared_factor.real() + pml_k_squared_factor.imag());
159 for (
unsigned l = 0; l < n_node; l++)
165 local_eqn_real = nodal_local_eqn(l, u_index_helmholtz().real());
166 local_eqn_imag = nodal_local_eqn(l, u_index_helmholtz().imag());
169 if (local_eqn_real >= 0)
172 residuals[local_eqn_real] +=
173 (source.real() - (alpha_pml_k_squared_factor.real() * k_squared() *
174 interpolated_u.real() -
175 alpha_pml_k_squared_factor.imag() * k_squared() *
176 interpolated_u.imag())) *
180 for (
unsigned k = 0; k < DIM; k++)
182 residuals[local_eqn_real] +=
183 (pml_laplace_factor[k].real() * interpolated_dudx[k].real() -
184 pml_laplace_factor[k].imag() * interpolated_dudx[k].imag()) *
193 for (
unsigned l2 = 0; l2 < n_node; l2++)
196 nodal_local_eqn(l2, u_index_helmholtz().real());
198 nodal_local_eqn(l2, u_index_helmholtz().imag());
201 if (local_unknown_real >= 0)
204 for (
unsigned i = 0;
i < DIM;
i++)
206 jacobian(local_eqn_real, local_unknown_real) +=
207 pml_laplace_factor[
i].real() * dpsidx(l2,
i) *
211 jacobian(local_eqn_real, local_unknown_real) +=
212 -alpha_pml_k_squared_factor.real() * k_squared() * psi(l2) *
216 if (local_unknown_imag >= 0)
219 for (
unsigned i = 0;
i < DIM;
i++)
221 jacobian(local_eqn_real, local_unknown_imag) -=
222 pml_laplace_factor[
i].imag() * dpsidx(l2,
i) *
226 jacobian(local_eqn_real, local_unknown_imag) +=
227 alpha_pml_k_squared_factor.imag() * k_squared() * psi(l2) *
238 local_eqn_imag = nodal_local_eqn(l, u_index_helmholtz().imag());
239 local_eqn_real = nodal_local_eqn(l, u_index_helmholtz().real());
242 if (local_eqn_imag >= 0)
245 residuals[local_eqn_imag] +=
246 (source.imag() - (alpha_pml_k_squared_factor.imag() * k_squared() *
247 interpolated_u.real() +
248 alpha_pml_k_squared_factor.real() * k_squared() *
249 interpolated_u.imag())) *
253 for (
unsigned k = 0; k < DIM; k++)
255 residuals[local_eqn_imag] +=
256 (pml_laplace_factor[k].imag() * interpolated_dudx[k].real() +
257 pml_laplace_factor[k].real() * interpolated_dudx[k].imag()) *
266 for (
unsigned l2 = 0; l2 < n_node; l2++)
269 nodal_local_eqn(l2, u_index_helmholtz().imag());
271 nodal_local_eqn(l2, u_index_helmholtz().real());
274 if (local_unknown_imag >= 0)
277 for (
unsigned i = 0;
i < DIM;
i++)
279 jacobian(local_eqn_imag, local_unknown_imag) +=
280 pml_laplace_factor[
i].real() * dpsidx(l2,
i) *
284 jacobian(local_eqn_imag, local_unknown_imag) +=
285 -alpha_pml_k_squared_factor.real() * k_squared() * psi(l2) *
288 if (local_unknown_real >= 0)
291 for (
unsigned i = 0;
i < DIM;
i++)
293 jacobian(local_eqn_imag, local_unknown_real) +=
294 pml_laplace_factor[
i].imag() * dpsidx(l2,
i) *
298 jacobian(local_eqn_imag, local_unknown_real) +=
299 -alpha_pml_k_squared_factor.imag() * k_squared() * psi(l2) *
313 template<
unsigned DIM>
343 template<
unsigned DIM>
345 const unsigned& nplot)
351 outfile << tecplot_zone_string(nplot);
354 unsigned num_plot_points = nplot_points(nplot);
355 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
358 get_s_plot(iplot, nplot,
s);
359 std::complex<double> u(interpolated_u_pml_helmholtz(
s));
360 for (
unsigned i = 0;
i < DIM;
i++)
362 outfile << interpolated_x(
s,
i) <<
" ";
364 outfile << u.real() <<
" " << u.imag() << std::endl;
368 write_tecplot_zone_footer(outfile, nplot);
383 template<
unsigned DIM>
386 const unsigned& nplot)
392 outfile << tecplot_zone_string(nplot);
395 unsigned num_plot_points = nplot_points(nplot);
396 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
399 get_s_plot(iplot, nplot,
s);
400 std::complex<double> u(interpolated_u_pml_helmholtz(
s));
401 for (
unsigned i = 0;
i < DIM;
i++)
403 outfile << interpolated_x(
s,
i) <<
" ";
405 outfile << u.real() * cos(phi) + u.imag() * sin(phi) << std::endl;
409 write_tecplot_zone_footer(outfile, nplot);
425 template<
unsigned DIM>
427 std::ostream& outfile,
430 const unsigned& nplot)
442 outfile << tecplot_zone_string(nplot);
445 unsigned num_plot_points = nplot_points(nplot);
446 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
449 get_s_plot(iplot, nplot,
s);
450 std::complex<double> u(interpolated_u_pml_helmholtz(
s));
453 interpolated_x(
s, x);
456 (*incoming_wave_fct_pt)(x, incoming_soln);
458 for (
unsigned i = 0;
i < DIM;
i++)
460 outfile << interpolated_x(
s,
i) <<
" ";
463 outfile << (u.real() + incoming_soln[0]) * cos(phi) +
464 (u.imag() + incoming_soln[1]) * sin(phi)
469 write_tecplot_zone_footer(outfile, nplot);
483 template<
unsigned DIM>
486 const unsigned& nplot)
492 outfile << tecplot_zone_string(nplot);
495 unsigned num_plot_points = nplot_points(nplot);
496 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
499 get_s_plot(iplot, nplot,
s);
500 std::complex<double> u(interpolated_u_pml_helmholtz(
s));
501 for (
unsigned i = 0;
i < DIM;
i++)
503 outfile << interpolated_x(
s,
i) <<
" ";
505 outfile << u.imag() * cos(phi) - u.real() * sin(phi) << std::endl;
509 write_tecplot_zone_footer(outfile, nplot);
520 template<
unsigned DIM>
527 fprintf(file_pt,
"%s", tecplot_zone_string(nplot).c_str());
530 unsigned num_plot_points = nplot_points(nplot);
531 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
534 get_s_plot(iplot, nplot,
s);
535 std::complex<double> u(interpolated_u_pml_helmholtz(
s));
537 for (
unsigned i = 0;
i < DIM;
i++)
539 fprintf(file_pt,
"%g ", interpolated_x(
s,
i));
542 for (
unsigned i = 0;
i < DIM;
i++)
544 fprintf(file_pt,
"%g ", interpolated_x(
s,
i));
546 fprintf(file_pt,
"%g ", u.real());
547 fprintf(file_pt,
"%g \n", u.imag());
551 write_tecplot_zone_footer(file_pt, nplot);
563 template<
unsigned DIM>
565 std::ostream& outfile,
566 const unsigned& nplot,
576 outfile << tecplot_zone_string(nplot);
582 unsigned num_plot_points = nplot_points(nplot);
583 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
586 get_s_plot(iplot, nplot,
s);
589 interpolated_x(
s, x);
592 (*exact_soln_pt)(x, exact_soln);
595 for (
unsigned i = 0;
i < DIM;
i++)
597 outfile << x[
i] <<
" ";
599 outfile << exact_soln[0] <<
" " << exact_soln[1] << std::endl;
603 write_tecplot_zone_footer(outfile, nplot);
618 template<
unsigned DIM>
620 std::ostream& outfile,
622 const unsigned& nplot,
632 outfile << tecplot_zone_string(nplot);
638 unsigned num_plot_points = nplot_points(nplot);
639 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
642 get_s_plot(iplot, nplot,
s);
645 interpolated_x(
s, x);
648 (*exact_soln_pt)(x, exact_soln);
651 for (
unsigned i = 0;
i < DIM;
i++)
653 outfile << x[
i] <<
" ";
655 outfile << exact_soln[0] * cos(phi) + exact_soln[1] * sin(phi)
660 write_tecplot_zone_footer(outfile, nplot);
674 template<
unsigned DIM>
676 std::ostream& outfile,
678 const unsigned& nplot,
688 outfile << tecplot_zone_string(nplot);
694 unsigned num_plot_points = nplot_points(nplot);
695 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
698 get_s_plot(iplot, nplot,
s);
701 interpolated_x(
s, x);
704 (*exact_soln_pt)(x, exact_soln);
707 for (
unsigned i = 0;
i < DIM;
i++)
709 outfile << x[
i] <<
" ";
711 outfile << exact_soln[1] * cos(phi) - exact_soln[0] * sin(phi)
716 write_tecplot_zone_footer(outfile, nplot);
727 template<
unsigned DIM>
729 std::ostream& outfile,
745 unsigned n_node = nnode();
750 unsigned n_intpt = integral_pt()->nweight();
753 outfile <<
"ZONE" << std::endl;
759 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
762 for (
unsigned i = 0;
i < DIM;
i++)
764 s[
i] = integral_pt()->knot(ipt,
i);
768 double w = integral_pt()->weight(ipt);
771 double J = J_eulerian(
s);
777 interpolated_x(
s, x);
780 std::complex<double> u_fe = interpolated_u_pml_helmholtz(
s);
783 (*exact_soln_pt)(x, exact_soln);
786 for (
unsigned i = 0;
i < DIM;
i++)
788 outfile << x[
i] <<
" ";
790 outfile << exact_soln[0] <<
" " << exact_soln[1] <<
" "
791 << exact_soln[0] - u_fe.real() <<
" "
792 << exact_soln[1] - u_fe.imag() << std::endl;
796 (exact_soln[0] * exact_soln[0] + exact_soln[1] * exact_soln[1]) *
W;
797 error += ((exact_soln[0] - u_fe.real()) * (exact_soln[0] - u_fe.real()) +
798 (exact_soln[1] - u_fe.imag()) * (exact_soln[1] - u_fe.imag())) *
807 template<
unsigned DIM>
820 unsigned n_node = nnode();
825 unsigned n_intpt = integral_pt()->nweight();
828 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
831 for (
unsigned i = 0;
i < 2;
i++)
833 s[
i] = integral_pt()->knot(ipt,
i);
837 double w = integral_pt()->weight(ipt);
840 double J = J_eulerian(
s);
846 std::complex<double> u_fe = interpolated_u_pml_helmholtz(
s);
849 norm += (u_fe.real() * u_fe.real() + u_fe.imag() * u_fe.imag()) *
W;
860 template<
unsigned DIM>
A mapping function propsed by Bermudez et al, appears to be the best for the Helmholtz equations and ...
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as .
virtual unsigned self_test()
Self-test: Check inversion of element & do self-test for GeneralisedElement. Return 0 if OK.
A class for all isoparametric elements that solve the Helmholtz equations with pml capabilities....
virtual void fill_in_generic_residual_contribution_helmholtz(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Compute element residual Vector only (if flag=and/or element Jacobian matrix.
void output(std::ostream &outfile)
Output with default number of plot points.
void compute_norm(double &norm)
Compute norm of fe solution.
void output_imag_fct(std::ostream &outfile, const double &phi, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output function for imaginary part of full time-dependent fct u = Im( (u_r +i u_i) exp(-i omega t)) a...
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)) a...
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Get error against and norm of exact solution.
void output_imag(std::ostream &outfile, const double &phi, const unsigned &n_plot)
Output function for imaginary part of full time-dependent solution u = Im( (u_r +i u_i) exp(-i omega ...
static double Default_Physical_Constant_Value
Static default value for the physical constants (initialised to zero)
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output exact soln: x,y,u_re_exact,u_im_exact or x,y,z,u_re_exact,u_im_exact at n_plot^DIM plot points...
unsigned self_test()
Self-test: Return 0 for OK.
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...
void output_total_real(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt incoming_wave_fct_pt, const double &phi, const unsigned &nplot)
Output function for real part of full time-dependent solution constructed by adding the scattered fie...
//////////////////////////////////////////////////////////////////////// ////////////////////////////...
static const unsigned Initial_Nvalue
Static int that holds the number of variables at nodes: always the same.
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...