pml_helmholtz_elements.h
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Version 1.0; svn revision $LastChangedRevision$
7 //LIC//
8 //LIC// $LastChangedDate$
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 //Header file for Helmholtz elements
31 #ifndef OOMPH_PML_HELMHOLTZ_ELEMENTS_HEADER
32 #define OOMPH_PML_HELMHOLTZ_ELEMENTS_HEADER
33 
34 
35 // Config header generated by autoconfig
36 #ifdef HAVE_CONFIG_H
37 #include <oomph-lib-config.h>
38 #endif
39 
40 #include "math.h"
41 #include <complex>
42 
43 //OOMPH-LIB headers
44 #include "../generic/nodes.h"
45 #include "../generic/Qelements.h"
46 #include "../generic/oomph_utilities.h"
47 #include "../generic/pml_meshes.h"
48 #include "../generic/projection.h"
49 #include "../generic/pml_mapping_functions.h"
50 
51 ////////////////////////////////////////////////////////////////////
52 ////////////////////////////////////////////////////////////////////
53 ////////////////////////////////////////////////////////////////////
54 
55 namespace oomph
56 {
57 
58 //=============================================================
59 /// A class for all isoparametric elements that solve the
60 /// Helmholtz equations with PMLs, but without any of the PML
61 /// capability or depedence on a PML element template parameter
62 //=============================================================
63  template <unsigned DIM>
65  public virtual FiniteElement
66  {
67  public:
68 
69  /// \short Function pointer to source function fct(x,f(x)) --
70  /// x is a Vector!
71  typedef void (*PMLHelmholtzSourceFctPt)(const Vector<double>& x,
72  std::complex<double>& f);
73 
74  /// Constructor
76  Source_fct_pt(0),
77  K_squared_pt(0)
78  {
79  // Provide pointer to static data
81  }
82 
83 
84  /// Broken copy constructor
86  {
87  BrokenCopy::broken_copy("PMLHelmholtzEquationsBase");
88  }
89 
90  /// Broken assignment operator
91  // Commented out broken assignment operator because this can lead to a conflict warning
92  // when used in the virtual inheritence hierarchy. Essentially the compiler doesn't
93  // realise that two separate implementations of the broken function are the same and so,
94  // quite rightly, it shouts.
95  // void operator=(const PMLHelmholtzEquations&)
96  // {
97  // BrokenCopy::broken_assign("PMLHelmholtzEquations");
98  // }
99 
100  /// \short Return the index at which the unknown value
101  /// is stored.
102  virtual inline std::complex<unsigned> u_index_helmholtz() const
103  {return std::complex<unsigned>(0,1);}
104 
105  /// Get pointer to k_squared
106  double*& k_squared_pt(){ return K_squared_pt; }
107 
108  /// Get the square of wavenumber
109  double k_squared() const
110  {
111 #ifdef PARANOID
112  if (K_squared_pt==0)
113  {
114  throw OomphLibError(
115  "Please set pointer to k_squared using access fct to pointer!",
116  OOMPH_CURRENT_FUNCTION,
117  OOMPH_EXCEPTION_LOCATION);
118  }
119 #endif
120  return *K_squared_pt;
121  }
122 
123  /// Alpha, wavenumber complex shift
124  const double& alpha() const {return *Alpha_pt;}
125 
126  /// Pointer to Alpha, wavenumber complex shift
127  double* &alpha_pt() {return Alpha_pt;}
128 
129 
130  /// \short Number of scalars/fields output by this element. Reimplements
131  /// broken virtual function in base class.
132  unsigned nscalar_paraview() const
133  {
134  return 2;
135  }
136 
137  /// \short Write values of the i-th scalar field at the plot points. Needs
138  /// to be implemented for each new specific element type.
139  void scalar_value_paraview(std::ofstream& file_out,
140  const unsigned& i,
141  const unsigned& nplot) const
142  {
143 
144  //Vector of local coordinates
145  Vector<double> s(DIM);
146 
147  // Loop over plot points
148  unsigned num_plot_points=nplot_points_paraview(nplot);
149  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
150  {
151  // Get local coordinates of plot point
152  get_s_plot(iplot,nplot,s);
153  std::complex<double> u(interpolated_u_pml_helmholtz(s));
154 
155  // Paraview need to ouput the fields separately so it loops through all
156  // the elements twice
157  switch(i)
158  {
159  // Real part first
160  case 0:
161  file_out << u.real() << std::endl;
162  break;
163 
164  // Imaginary part second
165  case 1:
166  file_out << u.imag() << std::endl;
167  break;
168 
169  // Never get here
170  default:
171 #ifdef PARANOID
172  std::stringstream error_stream;
173  error_stream
174  << "PML Helmholtz elements only store 2 fields (real and imaginary) "
175  << "so i must be 0 or 1 rather "
176  << "than " << i << std::endl;
177  throw OomphLibError(
178  error_stream.str(),
179  OOMPH_CURRENT_FUNCTION,
180  OOMPH_EXCEPTION_LOCATION);
181 #endif
182  break;
183 
184  }
185  }
186  }
187 
188  /// \short Write values of the i-th scalar field at the plot points. Needs
189  /// to be implemented for each new specific element type.
190  void scalar_value_fct_paraview(std::ofstream& file_out,
191  const unsigned& i,
192  const unsigned& nplot,
194  exact_soln_pt) const
195  {
196  //Vector of local coordinates
197  Vector<double> s(DIM);
198 
199  // Vector for coordinates
200  Vector<double> x(DIM);
201 
202  // Exact solution Vector
203  Vector<double> exact_soln(2);
204 
205  // Loop over plot points
206  unsigned num_plot_points=nplot_points_paraview(nplot);
207  for (unsigned iplot=0;iplot<num_plot_points;iplot++)
208  {
209  // Get local coordinates of plot point
210  get_s_plot(iplot,nplot,s);
211 
212  // Get x position as Vector
213  interpolated_x(s,x);
214 
215  // Get exact solution at this point
216  (*exact_soln_pt)(x,exact_soln);
217 
218  // Paraview need to output the fields separately so it loops through all
219  // the elements twice
220  switch(i)
221  {
222  // Real part first
223  case 0:
224  file_out << exact_soln[0] << std::endl;
225  break;
226 
227  // Imaginary part second
228  case 1:
229  file_out << exact_soln[1] << std::endl;
230  break;
231 
232  // Never get here
233  default:
234 #ifdef PARANOID
235  std::stringstream error_stream;
236  error_stream
237  << "PML Helmholtz elements only store 2 fields (real and imaginary) "
238  << "so i must be 0 or 1 rather "
239  << "than " << i << std::endl;
240  throw OomphLibError(
241  error_stream.str(),
242  OOMPH_CURRENT_FUNCTION,
243  OOMPH_EXCEPTION_LOCATION);
244 #endif
245  break;
246 
247  }
248  }
249  }
250 
251  /// \short Name of the i-th scalar field. Default implementation
252  /// returns V1 for the first one, V2 for the second etc. Can (should!)
253  /// be overloaded with more meaningful names in specific elements.
254  std::string scalar_name_paraview(const unsigned& i) const
255  {
256  switch(i)
257  {
258  case 0:
259  return "Real part";
260  break;
261 
262  case 1:
263  return "Imaginary part";
264  break;
265 
266  // Never get here
267  default:
268 #ifdef PARANOID
269  std::stringstream error_stream;
270  error_stream
271  << "PML Helmholtz elements only store 2 fields (real and imaginary) "
272  << "so i must be 0 or 1 rather "
273  << "than " << i << std::endl;
274  throw OomphLibError(
275  error_stream.str(),
276  OOMPH_CURRENT_FUNCTION,
277  OOMPH_EXCEPTION_LOCATION);
278 #endif
279 
280  // Dummy return for the default statement
281  return " ";
282  break;
283  }
284  }
285 
286  /// Output with default number of plot points
287  void output(std::ostream &outfile)
288  {
289  const unsigned n_plot=5;
290  output(outfile,n_plot);
291  }
292 
293  /// \short Output FE representation of soln: x,y,u_re,u_im or
294  /// x,y,z,u_re,u_im at n_plot^DIM plot points
295  void output(std::ostream &outfile, const unsigned &n_plot);
296 
297  /// Output function for real part of full time-dependent solution
298  /// constructed by adding the scattered field
299  /// u = Re( (u_r +i u_i) exp(-i omega t)
300  /// at phase angle omega t = phi computed here, to the corresponding
301  /// incoming wave specified via the function pointer.
302  void output_total_real(
303  std::ostream &outfile,
304  FiniteElement::SteadyExactSolutionFctPt incoming_wave_fct_pt,
305  const double& phi,
306  const unsigned &nplot);
307 
308  /// \short Output function for real part of full time-dependent solution
309  /// u = Re( (u_r +i u_i) exp(-i omega t))
310  /// at phase angle omega t = phi.
311  /// x,y,u or x,y,z,u at n_plot plot points in each coordinate
312  /// direction
313  void output_real(std::ostream &outfile, const double& phi,
314  const unsigned &n_plot);
315 
316  /// \short Output function for imaginary part of full time-dependent solution
317  /// u = Im( (u_r +i u_i) exp(-i omega t) )
318  /// at phase angle omega t = phi.
319  /// x,y,u or x,y,z,u at n_plot plot points in each coordinate
320  /// direction
321  void output_imag(std::ostream &outfile, const double& phi,
322  const unsigned &n_plot);
323 
324  /// C_style output with default number of plot points
325  void output(FILE* file_pt)
326  {
327  const unsigned n_plot=5;
328  output(file_pt,n_plot);
329  }
330 
331  /// \short C-style output FE representation of soln: x,y,u_re,u_im or
332  /// x,y,z,u_re,u_im at n_plot^DIM plot points
333  void output(FILE* file_pt, const unsigned &n_plot);
334 
335  /// Output exact soln: x,y,u_re_exact,u_im_exact
336  /// or x,y,z,u_re_exact,u_im_exact at n_plot^DIM plot points
337  void output_fct(std::ostream &outfile, const unsigned &n_plot,
339 
340  /// \short Output exact soln: (dummy time-dependent version to
341  /// keep intel compiler happy)
342  virtual void output_fct(std::ostream &outfile, const unsigned &n_plot,
343  const double& time,
345  exact_soln_pt)
346  {
347  throw OomphLibError(
348  "There is no time-dependent output_fct() for PMLHelmholtz elements.",
349  OOMPH_CURRENT_FUNCTION,
350  OOMPH_EXCEPTION_LOCATION);
351  }
352 
353 
354 
355  /// \short Output function for real part of full time-dependent fct
356  /// u = Re( (u_r +i u_i) exp(-i omega t)
357  /// at phase angle omega t = phi.
358  /// x,y,u or x,y,z,u at n_plot plot points in each coordinate
359  /// direction
360  void output_real_fct(std::ostream &outfile,
361  const double& phi,
362  const unsigned &n_plot,
364 
365  /// \short Output function for imaginary part of full time-dependent fct
366  /// u = Im( (u_r +i u_i) exp(-i omega t))
367  /// at phase angle omega t = phi.
368  /// x,y,u or x,y,z,u at n_plot plot points in each coordinate
369  /// direction
370  void output_imag_fct(std::ostream &outfile,
371  const double& phi,
372  const unsigned &n_plot,
374 
375 
376  /// Get error against and norm of exact solution
377  void compute_error(std::ostream &outfile,
379  double& error, double& norm);
380 
381 
382  /// Dummy, time dependent error checker
383  void compute_error(std::ostream &outfile,
385  const double& time, double& error, double& norm)
386  {
387  throw OomphLibError(
388  "There is no time-dependent compute_error() for PMLHelmholtz elements.",
389  OOMPH_CURRENT_FUNCTION,
390  OOMPH_EXCEPTION_LOCATION);
391  }
392 
393 
394  /// Compute norm of fe solution
395  void compute_norm(double& norm);
396 
397  /// Access function: Pointer to source function
399 
400  /// Access function: Pointer to source function. Const version
402 
403 
404  /// Get source term at (Eulerian) position x. This function is
405  /// virtual to allow overloading in multi-physics problems where
406  /// the strength of the source function might be determined by
407  /// another system of equations.
408  inline virtual void get_source_helmholtz(const unsigned& ipt,
409  const Vector<double>& x,
410  std::complex<double>& source) const
411  {
412  //If no source function has been set, return zero
413  if(Source_fct_pt==0)
414  {
415  source = std::complex<double>(0.0,0.0);
416  }
417  else
418  {
419  // Get source strength
420  (*Source_fct_pt)(x,source);
421  }
422  }
423 
424  /// \short Pure virtual function in which we specify the
425  /// values to be pinned (and set to zero) on the outer edge of
426  /// the pml layer. All of them! Vector is resized internally.
428  Vector<unsigned>& values_to_pin)
429  {
430  values_to_pin.resize(2);
431 
432  values_to_pin[0]=0;
433  values_to_pin[1]=1;
434  }
435 
436 
437  /// Get flux: flux[i] = du/dx_i for real and imag part
438  void get_flux(const Vector<double>& s,
439  Vector<std::complex <double> >& flux) const
440  {
441  //Find out how many nodes there are in the element
442  const unsigned n_node = nnode();
443 
444 
445  //Set up memory for the shape and test functions
446  Shape psi(n_node);
447  DShape dpsidx(n_node,DIM);
448 
449  //Call the derivatives of the shape and test functions
450  dshape_eulerian(s,psi,dpsidx);
451 
452  //Initialise to zero
453  const std::complex<double> zero(0.0,0.0);
454  for(unsigned j=0;j<DIM;j++)
455  {
456  flux[j] = zero;
457  }
458 
459  // Loop over nodes
460  for(unsigned l=0;l<n_node;l++)
461  {
462  //Cache the complex value of the unknown
463  const std::complex<double> u_value(
464  this->nodal_value(l,u_index_helmholtz().real()),
465  this->nodal_value(l,u_index_helmholtz().imag()));
466  //Loop over derivative directions
467  for(unsigned j=0;j<DIM;j++)
468  {
469  flux[j] += u_value*dpsidx(l,j);
470  }
471  }
472  }
473 
474  /// \short Return FE representation of function value u_helmholtz(s)
475  /// at local coordinate s
476  inline std::complex<double>
478  {
479  //Find number of nodes
480  const unsigned n_node = nnode();
481 
482  //Local shape function
483  Shape psi(n_node);
484 
485  //Find values of shape function
486  shape(s,psi);
487 
488  //Initialise value of u
489  std::complex<double> interpolated_u(0.0,0.0);
490 
491  //Get the index at which the helmholtz unknown is stored
492  const unsigned u_nodal_index_real = u_index_helmholtz().real();
493  const unsigned u_nodal_index_imag = u_index_helmholtz().imag();
494 
495  //Loop over the local nodes and sum
496  for(unsigned l=0;l<n_node;l++)
497  {
498  //Make a temporary complex number from the stored data
499  const std::complex<double> u_value(
500  this->nodal_value(l,u_nodal_index_real),
501  this->nodal_value(l,u_nodal_index_imag));
502  //Add to the interpolated value
503  interpolated_u += u_value*psi[l];
504  }
505  return interpolated_u;
506  }
507 
508 
509  /// \short Self-test: Return 0 for OK
510  unsigned self_test();
511 
512  /// \short The number of "DOF types" that degrees of freedom in this element
513  /// are sub-divided into: real and imaginary part
514  unsigned ndof_types() const
515  {
516  return 2;
517  }
518 
519  /// \short Create a list of pairs for all unknowns in this element,
520  /// so that the first entry in each pair contains the global equation
521  /// number of the unknown, while the second one contains the number
522  /// of the "DOF type" that this unknown is associated with.
523  /// (Function can obviously only be called if the equation numbering
524  /// scheme has been set up.) Real=0; Imag=1
526  std::list<std::pair<unsigned long,unsigned> >& dof_lookup_list) const
527  {
528  // temporary pair (used to store dof lookup prior to being added to list)
529  std::pair<unsigned,unsigned> dof_lookup;
530 
531  // number of nodes
532  unsigned n_node = this->nnode();
533 
534  // loop over the nodes
535  for (unsigned n = 0; n < n_node; n++)
536  {
537  // determine local eqn number for real part
538  int local_eqn_number =
539  this->nodal_local_eqn(n, u_index_helmholtz().real());
540 
541  // ignore pinned values
542  if (local_eqn_number >= 0)
543  {
544  // store dof lookup in temporary pair: First entry in pair
545  // is global equation number; second entry is dof type
546  dof_lookup.first = this->eqn_number(local_eqn_number);
547  dof_lookup.second = 0;
548 
549  // add to list
550  dof_lookup_list.push_front(dof_lookup);
551  }
552 
553  // determine local eqn number for imag part
554  local_eqn_number =
555  this->nodal_local_eqn(n, u_index_helmholtz().imag());
556 
557  // ignore pinned values
558  if (local_eqn_number >= 0)
559  {
560  // store dof lookup in temporary pair: First entry in pair
561  // is global equation number; second entry is dof type
562  dof_lookup.first = this->eqn_number(local_eqn_number);
563  dof_lookup.second = 1;
564 
565  // add to list
566  dof_lookup_list.push_front(dof_lookup);
567  }
568  }
569  }
570 
571 
572  protected:
573 
574  /// \short Shape/test functions and derivs w.r.t. to global coords at
575  /// local coord. s; return Jacobian of mapping
577  const Vector<double> &s,
578  Shape &psi,
579  DShape &dpsidx,
580  Shape &test,
581  DShape &dtestdx) const=0;
582 
583 
584  /// \short Shape/test functions and derivs w.r.t. to global coords at
585  /// integration point ipt; return Jacobian of mapping
587  const unsigned &ipt,
588  Shape &psi,
589  DShape &dpsidx,
590  Shape &test,
591  DShape &dtestdx) const=0;
592 
593  /// Pointer to wavenumber complex shift
594  double *Alpha_pt;
595 
596  /// Pointer to source function:
598 
599  /// Pointer to wave number (must be set!)
600  double* K_squared_pt;
601 
602  /// Static default value for the physical constants (initialised to zero)
604 
605  };
606 
607 
608  //=============================================================
609  /// A class for all isoparametric elements that solve the
610  /// Helmholtz equations with pml capabilities.
611  /// This contains the generic maths. Shape functions, geometric
612  /// mapping etc. must get implemented in derived class.
613  //=============================================================
614  template <unsigned DIM, class PML_ELEMENT>
616  public virtual FiniteElement,
617  public virtual PML_ELEMENT,
618  public virtual PMLHelmholtzEquationsBase<DIM>
619  {
620  public:
621 
622  /// Constructor
624  {
625  // Provide pointer to static method (Save memory)
626  this->Pml_mapping_pt = &PMLHelmholtzEquations::Default_pml_mapping;
627  }
628 
629  /// Add the element's contribution to its residual vector (wrapper)
631  {
632  //Call the generic residuals function with flag set to 0
633  //using a dummy matrix argument
634  fill_in_generic_residual_contribution_helmholtz(
636  }
637 
638 
639  /// \short Add the element's contribution to its residual vector and
640  /// element Jacobian matrix (wrapper)
642  DenseMatrix<double> &jacobian)
643  {
644  //Call the generic routine with the flag set to 1
645  fill_in_generic_residual_contribution_helmholtz(residuals,jacobian,1);
646  }
647 
648  /// Get wavenumber (used in PML)
649  double wavenumber() const { return std::sqrt(this->k_squared()); }
650 
651  /// Resolve amibiguity of which function to call between two base classes
653  Vector<unsigned>& values_to_pin)
654  {
656  }
657 
658  protected:
659  /// \short Compute element residual Vector only (if flag=and/or element
660  /// Jacobian matrix
661  virtual void fill_in_generic_residual_contribution_helmholtz(
662  Vector<double> &residuals, DenseMatrix<double> &jacobian,
663  const unsigned& flag);
664 
665  /// Static so that the class doesn't need to instantiate a new default
666  /// everytime it uses it
668  };
669 
670 
671 ///////////////////////////////////////////////////////////////////////////
672 ///////////////////////////////////////////////////////////////////////////
673 ///////////////////////////////////////////////////////////////////////////
674 
675 
676 
677 //======================================================================
678 /// \short QPMLHelmholtzElement elements are linear/quadrilateral/
679 /// brick-shaped PMLHelmholtz elements with isoparametric
680 /// interpolation for the function.
681 //======================================================================
682  template <unsigned DIM, unsigned NNODE_1D, class PML_ELEMENT>
683  class QPMLHelmholtzElement : public virtual QElement<DIM,NNODE_1D>,
684  public virtual PMLHelmholtzEquations<DIM, PML_ELEMENT>
685  {
686 
687  private:
688 
689  /// \short Static int that holds the number of variables at
690  /// nodes: always the same
691  static const unsigned Initial_Nvalue;
692 
693  public:
694 
695 
696  ///\short Constructor: Call constructors for QElement and
697  /// PMLHelmholtz equations
699  QElement<DIM,NNODE_1D>(), PMLHelmholtzEquations<DIM, PML_ELEMENT>()
700  {}
701 
702  /// Broken copy constructor
705  {
706  BrokenCopy::broken_copy("QPMLHelmholtzElement");
707  }
708 
709  /// Broken assignment operator
710  /*void operator=(const QPMLHelmholtzElement<DIM,NNODE_1D, PML_ELEMENT>&)
711  {
712  BrokenCopy::broken_assign("QPMLHelmholtzElement");
713  }*/
714 
715 
716  /// \short Required # of `values' (pinned or dofs)
717  /// at node n
718  inline unsigned required_nvalue(const unsigned &n) const
719  {return Initial_Nvalue;}
720 
721  /// \short Output function:
722  /// x,y,u or x,y,z,u
723  void output(std::ostream &outfile)
725 
726 
727  /// \short Output function:
728  /// x,y,u or x,y,z,u at n_plot^DIM plot points
729  void output(std::ostream &outfile, const unsigned &n_plot)
731 
732  /// \short Output function for real part of full time-dependent solution
733  /// u = Re( (u_r +i u_i) exp(-i omega t)
734  /// at phase angle omega t = phi.
735  /// x,y,u or x,y,z,u at n_plot plot points in each coordinate
736  /// direction
737  void output_real(std::ostream &outfile, const double& phi,
738  const unsigned &n_plot)
740 
741  /// \short Output function for imaginary part of full time-dependent solution
742  /// u = Im( (u_r +i u_i) exp(-i omega t))
743  /// at phase angle omega t = phi.
744  /// x,y,u or x,y,z,u at n_plot plot points in each coordinate
745  /// direction
746  void output_imag(std::ostream &outfile, const double& phi,
747  const unsigned &n_plot)
749 
750 
751  /// \short C-style output function:
752  /// x,y,u or x,y,z,u
753  void output(FILE* file_pt)
755 
756 
757  /// \short C-style output function:
758  /// x,y,u or x,y,z,u at n_plot^DIM plot points
759  void output(FILE* file_pt, const unsigned &n_plot)
761 
762 
763  /// \short Output function for an exact solution:
764  /// x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot points
765  void output_fct(std::ostream &outfile, const unsigned &n_plot,
768  n_plot,
769  exact_soln_pt);}
770 
771 
772  /// \short Output function for real part of full time-dependent fct
773  /// u = Re( (u_r +i u_i) exp(-i omega t)
774  /// at phase angle omega t = phi.
775  /// x,y,u or x,y,z,u at n_plot plot points in each coordinate
776  /// direction
777  void output_real_fct(std::ostream &outfile,
778  const double& phi,
779  const unsigned &n_plot,
781  {
783  phi,
784  n_plot,
785  exact_soln_pt);
786  }
787 
788  /// \short Output function for imaginary part of full time-dependent fct
789  /// u = Im( (u_r +i u_i) exp(-i omega t))
790  /// at phase angle omega t = phi.
791  /// x,y,u or x,y,z,u at n_plot plot points in each coordinate
792  /// direction
793  void output_imag_fct(std::ostream &outfile,
794  const double& phi,
795  const unsigned &n_plot,
797  {
799  phi,
800  n_plot,
801  exact_soln_pt);
802  }
803 
804 
805  /// \short Output function for a time-dependent exact solution.
806  /// x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot points
807  /// (Calls the steady version)
808  void output_fct(std::ostream &outfile, const unsigned &n_plot,
809  const double& time,
812  n_plot,
813  time,
814  exact_soln_pt);}
815 
816  protected:
817 
818 /// Shape, test functions & derivs. w.r.t. to global coords. Return Jacobian.
820  const Vector<double> &s, Shape &psi, DShape &dpsidx,
821  Shape &test, DShape &dtestdx) const;
822 
823 
824  /// \short Shape, test functions & derivs. w.r.t. to global coords. at
825  /// integration point ipt. Return Jacobian.
826  inline double dshape_and_dtest_eulerian_at_knot_helmholtz(const unsigned& ipt,
827  Shape &psi,
828  DShape &dpsidx,
829  Shape &test,
830  DShape &dtestdx)
831  const;
832 
833  };
834 
835 
836 
837 
838 //Inline functions:
839 
840 
841 //======================================================================
842 /// Define the shape functions and test functions and derivatives
843 /// w.r.t. global coordinates and return Jacobian of mapping.
844 ///
845 /// Galerkin: Test functions = shape functions
846 //======================================================================
847  template<unsigned DIM, unsigned NNODE_1D, class PML_ELEMENT>
849  const Vector<double> &s,
850  Shape &psi,
851  DShape &dpsidx,
852  Shape &test,
853  DShape &dtestdx) const
854  {
855  //Call the geometrical shape functions and derivatives
856  const double J = this->dshape_eulerian(s,psi,dpsidx);
857 
858  //Set the test functions equal to the shape functions
859  test = psi;
860  dtestdx= dpsidx;
861 
862  //Return the jacobian
863  return J;
864  }
865 
866 
867 
868 
869 //======================================================================
870 /// Define the shape functions and test functions and derivatives
871 /// w.r.t. global coordinates and return Jacobian of mapping.
872 ///
873 /// Galerkin: Test functions = shape functions
874 //======================================================================
875  template<unsigned DIM, unsigned NNODE_1D, class PML_ELEMENT>
878  const unsigned &ipt,
879  Shape &psi,
880  DShape &dpsidx,
881  Shape &test,
882  DShape &dtestdx) const
883  {
884  //Call the geometrical shape functions and derivatives
885  const double J = this->dshape_eulerian_at_knot(ipt,psi,dpsidx);
886 
887  //Set the pointers of the test functions
888  test = psi;
889  dtestdx = dpsidx;
890 
891  //Return the jacobian
892  return J;
893  }
894 
895 ////////////////////////////////////////////////////////////////////////
896 ////////////////////////////////////////////////////////////////////////
897 ////////////////////////////////////////////////////////////////////////
898 
899 
900 
901 //=======================================================================
902 /// Face geometry for the QPMLHelmholtzElement elements: The spatial
903 /// dimension of the face elements is one lower than that of the
904 /// bulk element but they have the same number of points
905 /// along their 1D edges.
906 //=======================================================================
907  template<unsigned DIM, unsigned NNODE_1D, class PML_ELEMENT>
908  class FaceGeometry<QPMLHelmholtzElement<DIM,NNODE_1D, PML_ELEMENT> >:
909  public virtual QElement<DIM-1,NNODE_1D>
910  {
911 
912  public:
913 
914  /// \short Constructor: Call the constructor for the
915  /// appropriate lower-dimensional QElement
916  FaceGeometry() : QElement<DIM-1,NNODE_1D>() {}
917 
918  };
919 
920 ////////////////////////////////////////////////////////////////////////
921 ////////////////////////////////////////////////////////////////////////
922 ////////////////////////////////////////////////////////////////////////
923 
924 
925 //=======================================================================
926 /// Face geometry for the 1D QPMLHelmholtzElement elements:
927 /// Point elements
928 //=======================================================================
929  template<unsigned NNODE_1D, class PML_ELEMENT>
930  class FaceGeometry<QPMLHelmholtzElement<1,NNODE_1D,PML_ELEMENT> >:
931  public virtual PointElement
932  {
933 
934  public:
935 
936  /// \short Constructor: Call the constructor for the
937  /// appropriate lower-dimensional QElement
939 
940  };
941 
942 
943 ////////////////////////////////////////////////////////////////////////
944 ////////////////////////////////////////////////////////////////////////
945 ////////////////////////////////////////////////////////////////////////
946 
947 
948 //==========================================================
949 /// PMLHelmholtz upgraded to become projectable
950 //==========================================================
951  template<class HELMHOLTZ_ELEMENT>
953  public virtual ProjectableElement<HELMHOLTZ_ELEMENT>
954  {
955 
956  public:
957 
958 
959  /// \short Constructor [this was only required explicitly
960  /// from gcc 4.5.2 onwards...]
962 
963  /// \short Specify the values associated with field fld.
964  /// The information is returned in a vector of pairs which comprise
965  /// the Data object and the value within it, that correspond to field fld.
967  {
968 
969 #ifdef PARANOID
970  if (fld>1)
971  {
972  std::stringstream error_stream;
973  error_stream
974  << "PMLHelmholtz elements only store 2 fields so fld = "
975  << fld << " is illegal \n";
976  throw OomphLibError(
977  error_stream.str(),
978  OOMPH_CURRENT_FUNCTION,
979  OOMPH_EXCEPTION_LOCATION);
980  }
981 #endif
982 
983  // Create the vector
984  unsigned nnod=this->nnode();
985  Vector<std::pair<Data*,unsigned> > data_values(nnod);
986 
987  // Loop over all nodes
988  for (unsigned j=0;j<nnod;j++)
989  {
990  // Add the data value associated field: The node itself
991  data_values[j]=std::make_pair(this->node_pt(j),fld);
992  }
993 
994  // Return the vector
995  return data_values;
996  }
997 
998  /// \short Number of fields to be projected: 2 (real and imag part)
1000  {
1001  return 2;
1002  }
1003 
1004  /// \short Number of history values to be stored for fld-th field.
1005  /// (Note: count includes current value!)
1006  unsigned nhistory_values_for_projection(const unsigned &fld)
1007  {
1008 #ifdef PARANOID
1009  if (fld>1)
1010  {
1011  std::stringstream error_stream;
1012  error_stream
1013  << "PMLHelmholtz elements only store two fields so fld = "
1014  << fld << " is illegal\n";
1015  throw OomphLibError(
1016  error_stream.str(),
1017  OOMPH_CURRENT_FUNCTION,
1018  OOMPH_EXCEPTION_LOCATION);
1019  }
1020 #endif
1021  return this->node_pt(0)->ntstorage();
1022  }
1023 
1024  ///\short Number of positional history values
1025  /// (Note: count includes current value!)
1027  {
1028  return this->node_pt(0)->position_time_stepper_pt()->ntstorage();
1029  }
1030 
1031  /// \short Return Jacobian of mapping and shape functions of field fld
1032  /// at local coordinate s
1033  double jacobian_and_shape_of_field(const unsigned &fld,
1034  const Vector<double> &s,
1035  Shape &psi)
1036  {
1037 #ifdef PARANOID
1038  if (fld>1)
1039  {
1040  std::stringstream error_stream;
1041  error_stream
1042  << "PMLHelmholtz elements only store two fields so fld = "
1043  << fld << " is illegal.\n";
1044  throw OomphLibError(
1045  error_stream.str(),
1046  OOMPH_CURRENT_FUNCTION,
1047  OOMPH_EXCEPTION_LOCATION);
1048  }
1049 #endif
1050  unsigned n_dim=this->dim();
1051  unsigned n_node=this->nnode();
1052  Shape test(n_node);
1053  DShape dpsidx(n_node,n_dim), dtestdx(n_node,n_dim);
1054  double J=this->dshape_and_dtest_eulerian_helmholtz(s,psi,dpsidx,
1055  test,dtestdx);
1056  return J;
1057  }
1058 
1059 
1060 
1061  /// \short Return interpolated field fld at local coordinate s, at time level
1062  /// t (t=0: present; t>0: history values)
1063  double get_field(const unsigned &t,
1064  const unsigned &fld,
1065  const Vector<double>& s)
1066  {
1067 #ifdef PARANOID
1068  if (fld>1)
1069  {
1070  std::stringstream error_stream;
1071  error_stream
1072  << "PMLHelmholtz elements only store two fields so fld = "
1073  << fld << " is illegal\n";
1074  throw OomphLibError(
1075  error_stream.str(),
1076  OOMPH_CURRENT_FUNCTION,
1077  OOMPH_EXCEPTION_LOCATION);
1078  }
1079 #endif
1080  //Find the index at which the variable is stored
1081  std::complex<unsigned> complex_u_nodal_index = this->u_index_helmholtz();
1082  unsigned u_nodal_index = 0;
1083  if (fld==0)
1084  {
1085  u_nodal_index = complex_u_nodal_index.real();
1086  }
1087  else
1088  {
1089  u_nodal_index = complex_u_nodal_index.imag();
1090  }
1091 
1092 
1093  //Local shape function
1094  unsigned n_node=this->nnode();
1095  Shape psi(n_node);
1096 
1097  //Find values of shape function
1098  this->shape(s,psi);
1099 
1100  //Initialise value of u
1101  double interpolated_u = 0.0;
1102 
1103  //Sum over the local nodes
1104  for(unsigned l=0;l<n_node;l++)
1105  {
1106  interpolated_u += this->nodal_value(t,l,u_nodal_index)*psi[l];
1107  }
1108  return interpolated_u;
1109  }
1110 
1111 
1112 
1113 
1114  ///Return number of values in field fld: One per node
1115  unsigned nvalue_of_field(const unsigned &fld)
1116  {
1117 #ifdef PARANOID
1118  if (fld>1)
1119  {
1120  std::stringstream error_stream;
1121  error_stream
1122  << "PMLHelmholtz elements only store two fields so fld = "
1123  << fld << " is illegal\n";
1124  throw OomphLibError(
1125  error_stream.str(),
1126  OOMPH_CURRENT_FUNCTION,
1127  OOMPH_EXCEPTION_LOCATION);
1128  }
1129 #endif
1130  return this->nnode();
1131  }
1132 
1133 
1134  ///Return local equation number of value j in field fld.
1135  int local_equation(const unsigned &fld,
1136  const unsigned &j)
1137  {
1138 #ifdef PARANOID
1139  if (fld>1)
1140  {
1141  std::stringstream error_stream;
1142  error_stream
1143  << "PMLHelmholtz elements only store two fields so fld = "
1144  << fld << " is illegal\n";
1145  throw OomphLibError(
1146  error_stream.str(),
1147  OOMPH_CURRENT_FUNCTION,
1148  OOMPH_EXCEPTION_LOCATION);
1149  }
1150 #endif
1151  std::complex<unsigned> complex_u_nodal_index = this->u_index_helmholtz();
1152  unsigned u_nodal_index = 0;
1153  if (fld==0)
1154  {
1155  u_nodal_index = complex_u_nodal_index.real();
1156  }
1157  else
1158  {
1159  u_nodal_index = complex_u_nodal_index.imag();
1160  }
1161  return this->nodal_local_eqn(j,u_nodal_index);
1162  }
1163 
1164  /// \short Output FE representation of soln: x,y,u or x,y,z,u at
1165  /// n_plot^DIM plot points
1166  void output(std::ostream &outfile, const unsigned &nplot)
1167  {
1168  HELMHOLTZ_ELEMENT::output(outfile,nplot);
1169  }
1170 
1171 
1172  };
1173 
1174 
1175 //=======================================================================
1176 /// Face geometry for element is the same as that for the underlying
1177 /// wrapped element
1178 //=======================================================================
1179  template<class ELEMENT>
1181  : public virtual FaceGeometry<ELEMENT>
1182  {
1183  public:
1184  FaceGeometry() : FaceGeometry<ELEMENT>() {}
1185  };
1186 
1187 ////////////////////////////////////////////////////////////////////////
1188 ////////////////////////////////////////////////////////////////////////
1189 ////////////////////////////////////////////////////////////////////////
1190 
1191 //=======================================================================
1192 /// Policy class defining the elements to be used in the actual
1193 /// PML layers. Same!
1194 //=======================================================================
1195  template<unsigned NNODE_1D, class PML_ELEMENT>
1197  QPMLHelmholtzElement<2,NNODE_1D,PML_ELEMENT> > :
1198  public virtual QPMLHelmholtzElement<2,NNODE_1D,PML_ELEMENT>
1199  {
1200 
1201  public:
1202 
1203  /// \short Constructor: Call the constructor for the
1204  /// appropriate QElement
1206  QPMLHelmholtzElement<2,NNODE_1D,PML_ELEMENT>()
1207  {}
1208 
1209  };
1210 
1211 } // End of Namespace oomph
1212 
1213 #endif
std::complex< double > interpolated_u_pml_helmholtz(const Vector< double > &s) const
Return FE representation of function value u_helmholtz(s) at local coordinate s.
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_fct(std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Output function for a time-dependent exact solution. x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot ...
double jacobian_and_shape_of_field(const unsigned &fld, const Vector< double > &s, Shape &psi)
Return Jacobian of mapping and shape functions of field fld at local coordinate s.
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
virtual void output_fct(std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Output exact soln: (dummy time-dependent version to keep intel compiler happy)
EquivalentQElement()
Constructor: Call the constructor for the appropriate QElement.
void output(std::ostream &outfile)
Output with default number of plot points.
QPMLHelmholtzElement()
Constructor: Call constructors for QElement and PMLHelmholtz equations.
virtual void get_s_plot(const unsigned &i, const unsigned &nplot, Vector< double > &s, const bool &shifted_to_interior=false) const
Get cector of local coordinates of plot point i (when plotting nplot points in each "coordinate direc...
Definition: elements.h:2978
virtual double dshape_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsidx) const
Return the geometric shape functions and also first derivatives w.r.t. global coordinates at the ipt-...
Definition: elements.cc:3254
virtual void output(std::ostream &outfile)
Output the element data — typically the values at the nodes in a format suitable for post-processing...
Definition: elements.h:2884
unsigned required_nvalue(const unsigned &n) const
Broken assignment operator.
std::string scalar_name_paraview(const unsigned &i) const
Name of the i-th scalar field. Default implementation returns V1 for the first one, V2 for the second etc. Can (should!) be overloaded with more meaningful names in specific elements.
unsigned nhistory_values_for_projection(const unsigned &fld)
Number of history values to be stored for fld-th field. (Note: count includes current value!) ...
virtual unsigned nplot_points_paraview(const unsigned &nplot) const
Return the number of actual plot points for paraview plot with parameter nplot. Broken virtual; can b...
Definition: elements.h:2712
PMLHelmholtz upgraded to become projectable.
cstr elem_len * i
Definition: cfortran.h:607
PMLHelmholtzSourceFctPt Source_fct_pt
Pointer to source function:
void scalar_value_paraview(std::ofstream &file_out, const unsigned &i, const unsigned &nplot) const
Write values of the i-th scalar field at the plot points. Needs to be implemented for each new specif...
void compute_norm(double &norm)
Compute norm of fe solution.
ProjectablePMLHelmholtzElement()
Constructor [this was only required explicitly from gcc 4.5.2 onwards...].
PMLHelmholtzSourceFctPt & source_fct_pt()
Access function: Pointer to source function.
int local_equation(const unsigned &fld, const unsigned &j)
Return local equation number of value j in field fld.
A general Finite Element class.
Definition: elements.h:1274
const double & alpha() const
Alpha, wavenumber complex shift.
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Function pointer for function that computes Vector-valued time-dependent function as ...
Definition: elements.h:1729
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 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 ...
double dshape_and_dtest_eulerian_at_knot_helmholtz(const unsigned &ipt, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const
Shape, test functions & derivs. w.r.t. to global coords. at integration point ipt. Return Jacobian.
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
char t
Definition: cfortran.h:572
TimeStepper *& position_time_stepper_pt()
Return a pointer to the position timestepper.
Definition: nodes.h:969
void get_flux(const Vector< double > &s, Vector< std::complex< double > > &flux) const
Get flux: flux[i] = du/dx_i for real and imag part.
double wavenumber() const
Get wavenumber (used in PML)
void output(std::ostream &outfile, const unsigned &n_plot)
Output function: x,y,u or x,y,z,u at n_plot^DIM plot points.
void output(FILE *file_pt)
C-style output function: x,y,u or x,y,z,u.
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...
double *& alpha_pt()
Pointer to Alpha, wavenumber complex shift.
unsigned ndof_types() const
The number of "DOF types" that degrees of freedom in this element are sub-divided into: real and imag...
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 ...
double *& k_squared_pt()
Get pointer to k_squared.
virtual double dshape_and_dtest_eulerian_helmholtz(const Vector< double > &s, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const =0
Shape/test functions and derivs w.r.t. to global coords at local coord. s; return Jacobian of mapping...
PMLHelmholtzEquationsBase(const PMLHelmholtzEquationsBase &dummy)
Broken copy constructor.
PMLHelmholtzSourceFctPt source_fct_pt() const
Access function: Pointer to source function. Const version.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Add the element&#39;s contribution to its residual vector and element Jacobian matrix (wrapper) ...
void output(std::ostream &outfile)
Output function: x,y,u or x,y,z,u.
virtual void get_source_helmholtz(const unsigned &ipt, const Vector< double > &x, std::complex< double > &source) const
void get_dof_numbers_for_unknowns(std::list< std::pair< unsigned long, unsigned > > &dof_lookup_list) const
Create a list of pairs for all unknowns in this element, so that the first entry in each pair contain...
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(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as ...
Definition: elements.h:1723
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
Definition: elements.cc:3881
double * K_squared_pt
Pointer to wave number (must be set!)
double dshape_eulerian(const Vector< double > &s, Shape &psi, DShape &dpsidx) const
Compute the geometric shape functions and also first derivatives w.r.t. global coordinates at local c...
Definition: elements.cc:3227
void output(std::ostream &outfile, const unsigned &nplot)
Output FE representation of soln: x,y,u or x,y,z,u at n_plot^DIM plot points.
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element&#39;s contribution to its residual vector (wrapper)
static char t char * s
Definition: cfortran.h:572
void output(FILE *file_pt)
C_style output with default number of plot points.
unsigned long eqn_number(const unsigned &ieqn_local) const
Return the global equation number corresponding to the ieqn_local-th local equation number...
Definition: elements.h:709
unsigned nhistory_values_for_coordinate_projection()
Number of positional history values (Note: count includes current value!)
virtual void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output an exact solution over the element.
Definition: elements.h:2938
static const unsigned Initial_Nvalue
Static int that holds the number of variables at nodes: always the same.
unsigned nfields_for_projection()
Number of fields to be projected: 2 (real and imag part)
void values_to_be_pinned_on_outer_pml_boundary(Vector< unsigned > &values_to_pin)
Pure virtual function in which we specify the values to be pinned (and set to zero) on the outer edge...
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output function for an exact solution: x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot points...
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2109
void output(std::ostream &outfile)
Output with default number of plot points.
unsigned nvalue_of_field(const unsigned &fld)
Return number of values in field fld: One per node.
double k_squared() const
Get the square of wavenumber.
double nodal_value(const unsigned &n, const unsigned &i) const
Return the i-th value stored at local node n. Produces suitably interpolated values for hanging nodes...
Definition: elements.h:2470
unsigned ntstorage() const
Return the number of doubles required to represent history (one for steady)
Definition: timesteppers.h:562
unsigned self_test()
Self-test: Return 0 for OK.
unsigned ntstorage() const
Return total number of doubles stored per value to record time history of each value (one for steady ...
Definition: nodes.cc:847
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function: x,y,u or x,y,z,u at n_plot^DIM plot points.
double * Alpha_pt
Pointer to wavenumber complex shift.
virtual double dshape_and_dtest_eulerian_at_knot_helmholtz(const unsigned &ipt, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const =0
Shape/test functions and derivs w.r.t. to global coords at integration point ipt; return Jacobian of ...
unsigned nscalar_paraview() const
Number of scalars/fields output by this element. Reimplements broken virtual function in base class...
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
Definition: elements.h:2482
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...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn&#39;t been defined.
void scalar_value_fct_paraview(std::ofstream &file_out, const unsigned &i, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt) const
Write values of the i-th scalar field at the plot points. Needs to be implemented for each new specif...
virtual std::complex< unsigned > u_index_helmholtz() const
Broken assignment operator.
void values_to_be_pinned_on_outer_pml_boundary(Vector< unsigned > &values_to_pin)
Resolve amibiguity of which function to call between two base classes.
double get_field(const unsigned &t, const unsigned &fld, const Vector< double > &s)
Return interpolated field fld at local coordinate s, at time level t (t=0: present; t>0: history valu...
FaceGeometry()
Constructor: Call the constructor for the appropriate lower-dimensional QElement. ...
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...
static double Default_Physical_Constant_Value
Static default value for the physical constants (initialised to zero)
void compute_error(std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
Dummy, time dependent error checker.
QPMLHelmholtzElement elements are linear/quadrilateral/ brick-shaped PMLHelmholtz elements with isopa...
void output_total_real(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt incoming_wave_fct_pt, const double &phi, const unsigned &nplot)
double dshape_and_dtest_eulerian_helmholtz(const Vector< double > &s, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const
Shape, test functions & derivs. w.r.t. to global coords. Return Jacobian.
int local_eqn_number(const unsigned long &ieqn_global) const
Return the local equation number corresponding to the ieqn_global-th global equation number...
Definition: elements.h:731
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2146
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...
virtual void shape(const Vector< double > &s, Shape &psi) const =0
Calculate the geometric shape functions at local coordinate s. This function must be overloaded for e...
static DenseMatrix< double > Dummy_matrix
Empty dense matrix used as a dummy argument to combined residual and jacobian functions in the case w...
Definition: elements.h:228
FaceGeometry()
Constructor: Call the constructor for the appropriate lower-dimensional QElement. ...
void(* PMLHelmholtzSourceFctPt)(const Vector< double > &x, std::complex< double > &f)
Function pointer to source function fct(x,f(x)) – x is a Vector!
Vector< std::pair< Data *, unsigned > > data_values_of_field(const unsigned &fld)
Specify the values associated with field fld. The information is returned in a vector of pairs which ...
static BermudezPMLMapping Default_pml_mapping
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Return the local equation number corresponding to the i-th value at the n-th local node...
Definition: elements.h:1386