pml_fourier_decomposed_helmholtz_flux_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: 1259 $
7 //LIC//
8 //LIC// $LastChangedDate: 2016-11-08 23:52:03 +0000 (Tue, 08 Nov 2016) $
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 elements that are used to apply prescribed flux
31 // boundary conditions to the Fourier decomposed Helmholtz equations
32 #ifndef OOMPH_PML_FOURIER_DECOMPOSED_HELMHOLTZ_FLUX_ELEMENTS_HEADER
33 #define OOMPH_PML_FOURIER_DECOMPOSED_HELMHOLTZ_FLUX_ELEMENTS_HEADER
34 
35 
36 // Config header generated by autoconfig
37 #ifdef HAVE_CONFIG_H
38 #include <oomph-lib-config.h>
39 #endif
40 
41 #include "math.h"
42 #include <complex>
43 
44 // oomph-lib includes
45 #include "../generic/Qelements.h"
46 
47 
48 namespace oomph
49 {
50 
51 //======================================================================
52 /// \short A class for elements that allow the imposition of an
53 /// applied flux on the boundaries of Fourier decomposed Helmholtz elements.
54 /// The element geometry is obtained from the FaceGeometry<ELEMENT>
55 /// policy class.
56 //======================================================================
57  template <class ELEMENT>
59  public virtual FaceGeometry<ELEMENT>,
60  public virtual FaceElement
61  {
62 
63  public:
64 
65  /// \short Function pointer to the prescribed-flux function fct(x,f(x)) --
66  /// x is a Vector and the flux is a complex
67 
69  (const Vector<double>& x, std::complex<double>& flux);
70 
71  /// \short Constructor, takes the pointer to the "bulk" element and the
72  /// index of the face to which the element is attached.
74  FiniteElement* const &bulk_el_pt,
75  const int& face_index);
76 
77  ///\short Broken empty constructor
79  {
80  throw OomphLibError(
81  "Don't call empty constructor for PMLFourierDecomposedHelmholtzFluxElement",
82  OOMPH_CURRENT_FUNCTION,
83  OOMPH_EXCEPTION_LOCATION);
84  }
85 
86  /// Broken copy constructor
89  {
91  ("PMLFourierDecomposedHelmholtzFluxElement");
92  }
93 
94  /// Broken assignment operator
95 //Commented out broken assignment operator because this can lead to a conflict warning
96 //when used in the virtual inheritence hierarchy. Essentially the compiler doesn't
97 //realise that two separate implementations of the broken function are the same and so,
98 //quite rightly, it shouts.
99  /*void operator=(const PMLFourierDecomposedHelmholtzFluxElement&)
100  {
101  BrokenCopy::broken_assign
102  ("PMLFourierDecomposedHelmholtzFluxElement");
103  }*/
104 
105 
106  /// Access function for the prescribed-flux function pointer
108  {return Flux_fct_pt;}
109 
110 
111  /// Add the element's contribution to its residual vector
113  {
114  //Call the generic residuals function with flag set to 0
115  //using a dummy matrix argument
118  }
119 
120 
121  /// \short Add the element's contribution to its residual vector and its
122  /// Jacobian matrix
124  DenseMatrix<double> &jacobian)
125  {
126  //Call the generic routine with the flag set to 1
128  (residuals,jacobian,1);
129  }
130 
131  /// Output function -- forward to broken version in FiniteElement
132  /// until somebody decides what exactly they want to plot here...
133  void output(std::ostream &outfile) {FiniteElement::output(outfile);}
134 
135  /// \short Output function -- forward to broken version in FiniteElement
136  /// until somebody decides what exactly they want to plot here...
137  void output(std::ostream &outfile, const unsigned &n_plot)
138  {FiniteElement::output(outfile,n_plot);}
139 
140 
141  /// C-style output function -- forward to broken version in FiniteElement
142  /// until somebody decides what exactly they want to plot here...
143  void output(FILE* file_pt) {FiniteElement::output(file_pt);}
144 
145  /// \short C-style output function -- forward to broken version in
146  /// FiniteElement until somebody decides what exactly they want to plot
147  /// here...
148  void output(FILE* file_pt, const unsigned &n_plot)
149  {FiniteElement::output(file_pt,n_plot);}
150 
151 
152  /// \short Return the index at which the unknown value
153  /// is stored. (Real/imag part gives real index of real/imag part).
154  virtual inline std::complex<unsigned>
156  {
157  return std::complex<unsigned>(
160  }
161 
162 
163  protected:
164 
165  /// \short Function to compute the shape and test functions and to return
166  /// the Jacobian of mapping between local and global (Eulerian)
167  /// coordinates
168  inline double shape_and_test(const Vector<double> &s, Shape &psi,
169  Shape &test)
170  const
171  {
172  //Find number of nodes
173  unsigned n_node = nnode();
174 
175  //Get the shape functions
176  shape(s,psi);
177 
178  //Set the test functions to be the same as the shape functions
179  for(unsigned i=0;i<n_node;i++) {test[i] = psi[i];}
180 
181  //Return the value of the jacobian
182  return J_eulerian(s);
183  }
184 
185 
186  /// \short Function to compute the shape and test functions and to return
187  /// the Jacobian of mapping between local and global (Eulerian)
188  /// coordinates
189  inline double shape_and_test_at_knot(const unsigned &ipt,
190  Shape &psi, Shape &test)
191  const
192  {
193  //Find number of nodes
194  unsigned n_node = nnode();
195 
196  //Get the shape functions
197  shape_at_knot(ipt,psi);
198 
199  //Set the test functions to be the same as the shape functions
200  for(unsigned i=0;i<n_node;i++) {test[i] = psi[i];}
201 
202  //Return the value of the jacobian
203  return J_eulerian_at_knot(ipt);
204  }
205 
206 
207  /// Function to calculate the prescribed flux at a given spatial
208  /// position
209  void get_flux(const Vector<double>& x, std::complex<double>& flux)
210  {
211  //If the function pointer is zero return zero
212  if(Flux_fct_pt == 0)
213  {
214  flux = std::complex<double>(0.0,0.0);
215  }
216  //Otherwise call the function
217  else
218  {
219  (*Flux_fct_pt)(x,flux);
220  }
221  }
222 
223 
224  /// \short The index at which the real and imag part of the
225  /// unknown is stored at the nodes
227 
228 
229  /// \short Add the element's contribution to its residual vector.
230  /// flag=1(or 0): do (or don't) compute the contribution to the
231  /// Jacobian as well.
232  virtual void
234  Vector<double> &residuals, DenseMatrix<double> &jacobian,
235  const unsigned& flag);
236 
237 
238  /// Function pointer to the (global) prescribed-flux function
240 
241  };
242 
243 //////////////////////////////////////////////////////////////////////
244 //////////////////////////////////////////////////////////////////////
245 //////////////////////////////////////////////////////////////////////
246 
247 
248 
249 //===========================================================================
250 /// Constructor, takes the pointer to the "bulk" element, the
251 /// index of the fixed local coordinate and its value represented
252 /// by an integer (+/- 1), indicating that the face is located
253 /// at the max. or min. value of the "fixed" local coordinate
254 /// in the bulk element.
255 //===========================================================================
256  template<class ELEMENT>
259  FiniteElement* const &bulk_el_pt,
260  const int &face_index) :
261  FaceGeometry<ELEMENT>(), FaceElement()
262  {
263  // Let the bulk element build the FaceElement, i.e. setup the pointers
264  // to its nodes (by referring to the appropriate nodes in the bulk
265  // element), etc.
266  bulk_el_pt->build_face_element(face_index,this);
267 
268  // Initialise the prescribed-flux function pointer to zero
269  Flux_fct_pt = 0;
270 
271  // Initialise index at which real and imag unknowns are stored
273  std::complex<unsigned>(0,1);
274 
275  // Now read out indices from bulk element
277  dynamic_cast<PMLFourierDecomposedHelmholtzEquations*>(bulk_el_pt);
278  //If the cast has failed die
279  if(eqn_pt==0)
280  {
281  std::string error_string =
282  "Bulk element must inherit from PMLFourierDecomposedHelmholtzEquations.";
283  throw OomphLibError(
284  error_string,
285  OOMPH_CURRENT_FUNCTION,
286  OOMPH_EXCEPTION_LOCATION);
287  }
288  else
289  {
290  //Read the index from the (cast) bulk element
292  eqn_pt->u_index_pml_fourier_decomposed_helmholtz();
293  }
294 
295  }
296 
297 
298 //===========================================================================
299 /// Compute the element's residual vector and the (zero) Jacobian matrix.
300 //===========================================================================
301  template<class ELEMENT>
304  Vector<double> &residuals, DenseMatrix<double> &jacobian,
305  const unsigned& flag)
306  {
307  //Find out how many nodes there are3
308  const unsigned n_node = nnode();
309 
310  //Set up memory for the shape and test functions
311  Shape psif(n_node), testf(n_node);
312 
313  //Set the value of Nintpt
314  const unsigned n_intpt = integral_pt()->nweight();
315 
316  //Set the Vector to hold local coordinates
317  Vector<double> s(1);
318 
319  //Integers to hold the local equation and unknown numbers
320  int local_eqn_real=0 ,local_eqn_imag=0;
321 
322  //Loop over the integration points
323  //--------------------------------
324  for(unsigned ipt=0;ipt<n_intpt;ipt++)
325  {
326 
327  //Assign values of s
328  for(unsigned i=0;i<1;i++) {s[i] = integral_pt()->knot(ipt,i);}
329 
330  //Get the integral weight
331  double w = integral_pt()->weight(ipt);
332 
333  //Find the shape and test functions and return the Jacobian
334  //of the mapping
335  double J = shape_and_test(s,psif,testf);
336 
337  //Premultiply the weights and the Jacobian
338  double W = w*J;
339 
340  //Need to find position to feed into flux function, initialise to zero
341  Vector<double> interpolated_x(2,0.0);
342 
343  //Calculate coordinates
344  for(unsigned l=0;l<n_node;l++)
345  {
346  //Loop over coordinates
347  for(unsigned i=0;i<2;i++)
348  {
349  interpolated_x[i] += nodal_position(l,i)*psif[l];
350  }
351  }
352 
353  //first component
354  double r = interpolated_x[0];
355 
356  //Get the imposed flux
357  std::complex<double> flux(0.0,0.0);
358  get_flux(interpolated_x,flux);
359 
360  //Now add to the appropriate equations
361  //Loop over the test functions
362  for(unsigned l=0;l<n_node;l++)
363  {
364  local_eqn_real =
365  nodal_local_eqn
366  (l,U_index_pml_fourier_decomposed_helmholtz.real());
367 
368  /*IF it's not a boundary condition*/
369  if(local_eqn_real >= 0)
370  {
371  //Add the prescribed flux terms
372  residuals[local_eqn_real] -= flux.real()*testf[l]*r*W;
373 
374  // Imposed traction doesn't depend upon the solution,
375  // --> the Jacobian is always zero, so no Jacobian
376  // terms are required
377  }
378  local_eqn_imag =
379  nodal_local_eqn
380  (l,U_index_pml_fourier_decomposed_helmholtz.imag());
381 
382  /*IF it's not a boundary condition*/
383  if(local_eqn_imag >= 0)
384  {
385  //Add the prescribed flux terms
386  residuals[local_eqn_imag] -= flux.imag()*testf[l]*r*W;
387 
388  // Imposed traction doesn't depend upon the solution,
389  // --> the Jacobian is always zero, so no Jacobian
390  // terms are required
391  }
392  }
393  }
394  }
395 
396 
397 
398 
399 /////////////////////////////////////////////////////////////////////
400 /////////////////////////////////////////////////////////////////////
401 /////////////////////////////////////////////////////////////////////
402 
403 
404 //======================================================================
405 /// \short A class for elements that allow postprocessing of the
406 /// results -- currently computes radiated power over domain
407 /// boundaries.
408 /// The element geometry is obtained from the FaceGeometry<ELEMENT>
409 /// policy class.
410 //======================================================================
411 template <class ELEMENT>
413 public virtual FaceGeometry<ELEMENT>,
414  public virtual FaceElement
415  {
416  public:
417 
418  /// \short Constructor, takes the pointer to the "bulk" element and the
419  /// index of the face to which the element is attached.
421  (FiniteElement* const &bulk_el_pt,
422  const int& face_index);
423 
424  ///\short Broken empty constructor
426  {
427  throw OomphLibError(
428  "Don't call empty constructor for PMLFourierDecomposedHelmholtzPowerMonitorElement",
429  OOMPH_CURRENT_FUNCTION,
430  OOMPH_EXCEPTION_LOCATION);
431  }
432 
433  /// Broken copy constructor
436  {
438  ("PMLFourierDecomposedHelmholtzPowerMonitorElement");
439  }
440 
441  /// Broken assignment operator
442  /*void operator=(const PMLFourierDecomposedHelmholtzPowerMonitorElement&)
443  {
444  BrokenCopy::broken_assign
445  ("PMLFourierDecomposedHelmholtzPowerMonitorElement");
446  }*/
447 
448 
449  /// \short Specify the value of nodal zeta from the face geometry
450  /// The "global" intrinsic coordinate of the element when
451  /// viewed as part of a geometric object should be given by
452  /// the FaceElement representation, by default (needed to break
453  /// indeterminacy if bulk element is SolidElement)
454  double zeta_nodal(const unsigned &n, const unsigned &k,
455  const unsigned &i) const
456  {return FaceElement::zeta_nodal(n,k,i);}
457 
458 
459  /// Output function -- forward to broken version in FiniteElement
460  /// until somebody decides what exactly they want to plot here...
461  void output(std::ostream &outfile) {FiniteElement::output(outfile);}
462 
463  /// \short Output function -- forward to broken version in FiniteElement
464  /// until somebody decides what exactly they want to plot here...
465  void output(std::ostream &outfile, const unsigned &n_plot)
466  {FiniteElement::output(outfile,n_plot);}
467 
468  /// C-style output function -- forward to broken version in FiniteElement
469  /// until somebody decides what exactly they want to plot here...
470  void output(FILE* file_pt) {FiniteElement::output(file_pt);}
471 
472  /// \short C-style output function -- forward to broken version in
473  /// FiniteElement until somebody decides what exactly they want to plot
474  /// here...
475  void output(FILE* file_pt, const unsigned &n_plot)
476  {FiniteElement::output(file_pt,n_plot);}
477 
478  /// \short Return the index at which the real/imag unknown value
479  /// is stored.
480  virtual inline std::complex<unsigned>
482  const
483  {
484  return std::complex<unsigned>(
487  }
488 
489  /// \short Compute the element's contribution to the time-averaged
490  /// radiated power over the artificial boundary.
491  /// NOTE: This may give the wrong result
492  /// if the constitutive parameters genuinely vary!
494  {
495  // Dummy output file
496  std::ofstream outfile;
497  return global_power_contribution(outfile);
498  }
499 
500  /// \short Compute the element's contribution to the time-averaged
501  /// radiated power over the artificial boundary. Also output the
502  /// power density as a fct of the zenith angle in the specified
503  /// output file if it's open. NOTE: This may give the wrong result
504  /// if the constitutive parameters genuinely vary!
505  double global_power_contribution(std::ofstream& outfile)
506  {
507  // pointer to the corresponding bulk element
508  ELEMENT* bulk_elem_pt = dynamic_cast<ELEMENT*>(this->bulk_element_pt());
509 
510  // Number of nodes in bulk element
511  unsigned nnode_bulk=bulk_elem_pt->nnode();
512  const unsigned n_node_local = this->nnode();
513 
514  //get the dim of the bulk and local nodes
515  const unsigned bulk_dim= bulk_elem_pt->dim();
516  const unsigned local_dim= this->node_pt(0)->ndim();
517 
518  //Set up memory for the shape and test functions
519  Shape psi(n_node_local);
520 
521  //Set up memory for the shape functions
522  Shape psi_bulk(nnode_bulk);
523  DShape dpsi_bulk_dx(nnode_bulk,bulk_dim);
524 
525  //Set up memory for the outer unit normal
526  Vector< double > unit_normal(bulk_dim);
527 
528  //Set the value of n_intpt
529  const unsigned n_intpt = integral_pt()->nweight();
530 
531  //Set the Vector to hold local coordinates
532  Vector<double> s(local_dim-1);
533  double power=0.0;
534 
535  // Output?
536  if (outfile.is_open())
537  {
538  outfile << "ZONE\n";
539  }
540 
541  //Loop over the integration points
542  //--------------------------------
543  for(unsigned ipt=0;ipt<n_intpt;ipt++)
544  {
545  //Assign values of s
546  for(unsigned i=0;i<(local_dim-1);i++)
547  {
548  s[i] = integral_pt()->knot(ipt,i);
549  }
550  //get the outer_unit_ext vector
551  this->outer_unit_normal(s,unit_normal);
552 
553  //Get the integral weight
554  double w = integral_pt()->weight(ipt);
555 
556  // Get jacobian of mapping
557  double J=J_eulerian(s);
558 
559  //Premultiply the weights and the Jacobian
560  double W = w*J;
561 
562  // Get local coordinates in bulk element by copy construction
564 
565  //Call the derivatives of the shape functions
566  //in the bulk -- must do this via s because this point
567  //is not an integration point the bulk element!
568  (void)bulk_elem_pt->dshape_eulerian(s_bulk,psi_bulk,dpsi_bulk_dx);
569  this->shape(s,psi);
570 
571  // Derivs of Eulerian coordinates w.r.t. local coordinates
572  std::complex<double> dphi_dn(0.0,0.0);
573  Vector<std::complex <double> > interpolated_dphidx(bulk_dim);
574  std::complex<double> interpolated_phi(0.0,0.0);
575  Vector<double> x(bulk_dim);
576 
577  //Calculate function value and derivatives:
578  //-----------------------------------------
579  // Loop over nodes
580  for(unsigned l=0;l<nnode_bulk;l++)
581  {
582  //Get the nodal value of the helmholtz unknown
583  const std::complex<double> phi_value(
584  bulk_elem_pt->nodal_value(
585  l,bulk_elem_pt->
587  bulk_elem_pt->nodal_value(
588  l,bulk_elem_pt->
590  );
591 
592  //Loop over directions
593  for(unsigned i=0;i<bulk_dim;i++)
594  {
595  interpolated_dphidx[i] += phi_value*dpsi_bulk_dx(l,i);
596  }
597  } // End of loop over the bulk_nodes
598 
599  for(unsigned l=0;l<n_node_local;l++)
600  {
601  //Get the nodal value of the Helmholtz unknown
602  const std::complex<double> phi_value(
607 
608  interpolated_phi += phi_value*psi(l);
609  }
610 
611  //define dphi_dn
612  for(unsigned i=0;i<bulk_dim;i++)
613  {
614  dphi_dn += interpolated_dphidx[i]*unit_normal[i];
615  }
616 
617  // Power density
618  double integrand=
619  (interpolated_phi.real()*dphi_dn.imag()-
620  interpolated_phi.imag()*dphi_dn.real());
621 
622  interpolated_x(s,x);
623  double theta=atan2(x[0],x[1]);
624  // Output?
625  if (outfile.is_open())
626  {
627  outfile << x[0] << " "
628  << x[1] << " "
629  << theta << " "
630  << integrand << "\n";
631  }
632 
633  // ...add to integral
634  power+=MathematicalConstants::Pi*x[0]*integrand*W;
635  }
636 
637  return power;
638  }
639 
640  protected:
641 
642  /// \short Function to compute the test functions and to return
643  /// the Jacobian of mapping between local and global (Eulerian)
644  /// coordinates
645  inline double shape_and_test(const Vector<double> &s,
646  Shape& psi, Shape &test) const
647  {
648  //Get the shape functions
649  shape(s,test);
650 
651  unsigned nnod=nnode();
652  for (unsigned i=0;i<nnod;i++)
653  {
654  psi[i]=test[i];
655  }
656 
657  //Return the value of the jacobian
658  return J_eulerian(s);
659  }
660 
661  /// \short Function to compute the shape, test functions and derivates
662  /// and to return
663  /// the Jacobian of mapping between local and global (Eulerian)
664  /// coordinates
665  inline double d_shape_and_test_local(const Vector<double> &s, Shape &psi,
666  Shape &test,
667  DShape &dpsi_ds,DShape &dtest_ds)
668  const
669  {
670  //Find number of nodes
671  unsigned n_node = nnode();
672 
673  //Get the shape functions
674  dshape_local(s,psi,dpsi_ds);
675 
676  //Set the test functions to be the same as the shape functions
677  for(unsigned i=0;i<n_node;i++)
678  {
679  for(unsigned j=0;j<1;j++)
680  {
681  test[i] = psi[i];
682  dtest_ds(i,j)= dpsi_ds(i,j);
683  }
684  }
685  //Return the value of the jacobian
686  return J_eulerian(s);
687  }
688 
689  /// \short The index at which the real and imag part of the unknown
690  /// is stored at the nodes
692 
693  };
694 
695 
696 //////////////////////////////////////////////////////////////////////
697 //////////////////////////////////////////////////////////////////////
698 //////////////////////////////////////////////////////////////////////
699 
700 
701 //===========================================================================
702 /// Constructor, takes the pointer to the "bulk" element and the face index.
703 //===========================================================================
704 template<class ELEMENT>
707  (FiniteElement* const &bulk_el_pt,
708  const int &face_index) :
710  {
711  // Let the bulk element build the FaceElement, i.e. setup the pointers
712  // to its nodes (by referring to the appropriate nodes in the bulk
713  // element), etc.
714  bulk_el_pt->build_face_element(face_index,this);
715 
716  //Set up U_index_pml_fourier_decomposedhelmholtz.
717  U_index_pml_fourier_decomposed_helmholtz =
718  std::complex<unsigned>(0,1);
719 
720  // Cast to the appropriate PMLFourierDecomposedHelmholtzEquation
721  // so that we can find the index at which the variable is stored
722  // We assume that the dimension of the full problem is the same
723  // as the dimension of the node, if this is not the case you will have
724  // to write custom elements, sorry
726  dynamic_cast<PMLFourierDecomposedHelmholtzEquations*>(bulk_el_pt);
727  if(eqn_pt==0)
728  {
729  std::string error_string =
730  "Bulk element must inherit from PMLFourierDecomposedHelmholtzEquations.";
731  throw OomphLibError(
732  error_string,
733  OOMPH_CURRENT_FUNCTION,
734  OOMPH_EXCEPTION_LOCATION);
735  }
736  //Otherwise read out the value
737  else
738  {
739  //Read the index from the (cast) bulk element
740  U_index_pml_fourier_decomposed_helmholtz =
741  eqn_pt->u_index_pml_fourier_decomposed_helmholtz();
742  }
743  }
744 
745 }
746 
747 #endif
double shape_and_test(const Vector< double > &s, Shape &psi, Shape &test) const
Function to compute the shape and test functions and to return the Jacobian of mapping between local ...
double global_power_contribution(std::ofstream &outfile)
Compute the element's contribution to the time-averaged radiated power over the artificial boundary...
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector.
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
void output(std::ostream &outfile, const unsigned &n_plot)
Output function – forward to broken version in FiniteElement until somebody decides what exactly they...
PMLFourierDecomposedHelmholtzFluxElement(const PMLFourierDecomposedHelmholtzFluxElement &dummy)
Broken copy constructor.
double J_eulerian_at_knot(const unsigned &ipt) const
Return the Jacobian of the mapping from local to global coordinates at the ipt-th integration point O...
Definition: elements.cc:5121
double shape_and_test_at_knot(const unsigned &ipt, Shape &psi, Shape &test) const
Function to compute the shape and test functions and to return the Jacobian of mapping between local ...
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:2872
A class for elements that allow the imposition of an applied flux on the boundaries of Fourier decomp...
cstr elem_len * i
Definition: cfortran.h:607
int & face_index()
Index of the face (a number that uniquely identifies the face in the element)
Definition: elements.h:4367
const double Pi
50 digits from maple
PMLFourierDecomposedHelmholtzPrescribedFluxFctPt Flux_fct_pt
Function pointer to the (global) prescribed-flux function.
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:2458
A general Finite Element class.
Definition: elements.h:1271
double global_power_contribution()
Compute the element's contribution to the time-averaged radiated power over the artificial boundary...
void get_flux(const Vector< double > &s, Vector< double > &flux) const
Get flux: .
PMLFourierDecomposedHelmholtzPrescribedFluxFctPt & flux_fct_pt()
Broken assignment operator.
void outer_unit_normal(const Vector< double > &s, Vector< double > &unit_normal) const
Compute outer unit normal at the specified local coordinate.
Definition: elements.cc:5695
virtual double weight(const unsigned &i) const =0
Return weight of i-th integration point.
void output(std::ostream &outfile, const unsigned &n_plot)
Output function – forward to broken version in FiniteElement until somebody decides what exactly they...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Add the element's contribution to its residual vector and its Jacobian matrix.
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function – forward to broken version in FiniteElement until somebody decides what exac...
virtual std::complex< unsigned > u_index_pml_fourier_decomposed_helmholtz() const
Return the index at which the unknown value is stored. (Real/imag part gives real index of real/imag ...
static char t char * s
Definition: cfortran.h:572
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
Definition: elements.h:1900
void get_flux(const Vector< double > &x, std::complex< double > &flux)
virtual void shape_at_knot(const unsigned &ipt, Shape &psi) const
Return the geometric shape function at the ipt-th integration point.
Definition: elements.cc:3158
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2097
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function – forward to broken version in FiniteElement until somebody decides what exac...
double J_eulerian(const Vector< double > &s) const
Return the Jacobian of mapping from local to global coordinates at local position s...
Definition: elements.cc:5033
A class for elements that allow postprocessing of the results – currently computes radiated power ove...
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
In a FaceElement, the "global" intrinsic coordinate of the element along the boundary, when viewed as part of a compound geometric object is specified using the boundary coordinate defined by the mesh. Note: Boundary coordinates will have been set up when creating the underlying mesh, and their values will have been stored at the nodes.
Definition: elements.h:4251
double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s. Overloaded to get information from bulk...
Definition: elements.h:4277
virtual void fill_in_generic_residual_contribution_pml_fourier_decomposed_helmholtz_flux(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Add the element's contribution to its residual vector. flag=1(or 0): do (or don't) compute the contri...
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
double d_shape_and_test_local(const Vector< double > &s, Shape &psi, Shape &test, DShape &dpsi_ds, DShape &dtest_ds) const
Function to compute the shape, test functions and derivates and to return the Jacobian of mapping bet...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
Definition: elements.h:4470
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2134
Vector< double > local_coordinate_in_bulk(const Vector< double > &s) const
Return vector of local coordinates in bulk element, given the local coordinates in this FaceElement...
Definition: elements.cc:6032
virtual void build_face_element(const int &face_index, FaceElement *face_element_pt)
Function for building a lower dimensional FaceElement on the specified face of the FiniteElement...
Definition: elements.cc:4922
virtual std::complex< unsigned > u_index_pml_fourier_decomposed_helmholtz() const
Return the index at which the real/imag unknown value is stored.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition: nodes.h:992
std::complex< unsigned > U_index_pml_fourier_decomposed_helmholtz
The index at which the real and imag part of the unknown is stored at the nodes.
void(* PMLFourierDecomposedHelmholtzPrescribedFluxFctPt)(const Vector< double > &x, std::complex< double > &flux)
Function pointer to the prescribed-flux function fct(x,f(x)) – x is a Vector and the flux is a comple...
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...
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
Broken assignment operator.
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
virtual void dshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Function to compute the geometric shape functions and derivatives w.r.t. local coordinates at local c...
Definition: elements.h:1914
std::complex< unsigned > U_index_pml_fourier_decomposed_helmholtz
The index at which the real and imag part of the unknown is stored at the nodes.
double shape_and_test(const Vector< double > &s, Shape &psi, Shape &test) const
Function to compute the test functions and to return the Jacobian of mapping between local and global...