pml_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: 1282 $
7 //LIC//
8 //LIC// $LastChangedDate: 2017-01-16 08:27:53 +0000 (Mon, 16 Jan 2017) $
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 #ifndef OOMPH_PML_ELEMENT_HEADER
31 #define OOMPH_PML_ELEMENT_HEADER
32 
33 // Config header generated by autoconfig
34 #ifdef HAVE_CONFIG_H
35 #include <oomph-lib-config.h>
36 #endif
37 
38 #include "pml_mapping_functions.h"
39 #include "elements.h"
40 #include "complex_matrices.h"
41 
42 #include <complex>
43 
44 namespace oomph
45 {
46 
47 // typedef used to avoid inaccessible error in Rip struct
50 
51 //=======================================================================
52 /// Policy class for defining the equivalent quad element for any given
53 /// element. Used for constructing a structured PML around an unstructured
54 /// mesh. Needs to be instantiated for each bulk element class
55 //=======================================================================
56 template<class ELEMENT>
58 {
59 };
60 
61 //==============================================================
62 /// Base class for elements with pml capabilities
63 //==============================================================
64 template<unsigned DIM>
65 class PMLElementBase : public virtual FiniteElement
66 {
67 
68 public:
69 
70  /// Constructor
71  PMLElementBase() : Pml_is_enabled(false) {}
72 
73  /// Virtual destructor
74  virtual ~PMLElementBase(){}
75 
76  /// \short Disable pml
77  virtual void disable_pml()
78  {
79  Pml_is_enabled=false;
80  }
81 
82  /// \short Enable pml
83  virtual void enable_pml()
84  {
85  Pml_is_enabled=true;
86  }
87 
88  ///
89  virtual void pml_transformation_jacobian(
90  const unsigned& ipt,
91  const Vector<double>& s,
92  const Vector<double>& x,
93  DenseComplexMatrix& jacobian) = 0;
94 
95  ///
96  virtual void pml_transformation_jacobian(
97  const unsigned& ipt,
98  const Vector<double>& s,
99  const Vector<double>& x,
100  DenseComplexMatrix& jacobian_matrix,
101  Vector<std::complex<double> >& transformed_x) = 0;
102 
103  /// \short Pure virtual function in which we have to specify the
104  /// values to be pinned (and set to zero) on the outer edge of
105  /// the pml layer. This is usually all of the nodal values
106  /// (values 0 and 1 (real and imag part) for Helmholtz;
107  /// values 0,1,2 and 3 (real and imag part of x- and y-displacement
108  /// for 2D time-harmonic linear elasticity; etc.). Vector
109  /// must be resized internally!
110  virtual void values_to_be_pinned_on_outer_pml_boundary(
111  Vector<unsigned>& values_to_pin)=0;
112 
113  virtual double wavenumber() const
114  {
115  throw OomphLibError("PML elements must implement wavenumber()",
116  OOMPH_CURRENT_FUNCTION,
117  OOMPH_EXCEPTION_LOCATION);
118  }
119 
120  /// \short Computes laplace matrix (JJ^T)^-1|J| and determinant
121  /// |J| for jacobian J. Laplace matrix is so named because it
122  /// appears as the factor when the Laplace operator is transformed
123  static void compute_laplace_matrix_and_det(
124  const DenseComplexMatrix& jacobian,
125  DenseComplexMatrix& laplace_matrix,
126  std::complex<double>& jacobian_det);
127 
128  /// \short Computes laplace matrix (JJ^T)^-1|J| and determinant
129  /// |J| for diagonal matrix jacobian J. Laplace matrix is so named because it
130  /// appears as the factor when the Laplace operator is transformed
131  static void compute_laplace_matrix_and_det(
132  const DiagonalComplexMatrix& jacobian,
133  DiagonalComplexMatrix& laplace_matrix,
134  std::complex<double>& jacobian_det);
135 
136  /// \short Computes laplace matrix (JJ^T)^-1|J| and determinant
137  /// |J| for diagonal matrix jacobian J. Laplace matrix is so named because it
138  /// appears as the factor when the Laplace operator is transformed
139  static void compute_laplace_matrix_and_det(
140  const DiagonalComplexMatrix& jacobian,
141  DenseComplexMatrix& laplace_matrix,
142  std::complex<double>& jacobian_det);
143 
144  /// \short Computes the inverse J^-1 and determinant |J| of a Jacobian J
145  static void compute_jacobian_inverse_and_det(
146  const DiagonalComplexMatrix& jacobian,
147  DiagonalComplexMatrix& jacobian_inverse,
148  std::complex<double>& jacobian_det);
149 
150 protected:
151 
152  /// Boolean indicating if element is used in pml mode
154 
155 };
156 
157 
158 
159 template<unsigned DIM>
161 {
162 public:
163 
164  /// Constructor
166  Pml_direction_active(DIM,false),
167  Pml_inner_boundary(DIM,0.0),
168  Pml_outer_boundary(DIM,0.0)
169  {}
170 
171  ///
172  virtual void pml_transformation_jacobian(
173  const unsigned& ipt,
174  const Vector<double>& s,
175  const Vector<double>& x,
176  DiagonalComplexMatrix& jacobian);
177 
179  const unsigned& ipt,
180  const Vector<double>& s,
181  const Vector<double>& x,
182  DenseComplexMatrix& jacobian)
183  {
184  throw OomphLibError("AxisAlignedPMLElements produce diagonal matrices,"
185  "use the diagonal version of this function instead",
186  OOMPH_CURRENT_FUNCTION,
187  OOMPH_EXCEPTION_LOCATION);
188  }
189 
190  ///
191  virtual void pml_transformation_jacobian(
192  const unsigned& ipt,
193  const Vector<double>& s,
194  const Vector<double>& x,
195  DiagonalComplexMatrix& jacobian_matrix,
196  Vector<std::complex<double> >& transformed_x);
197 
198  ///
200  const unsigned& ipt,
201  const Vector<double>& s,
202  const Vector<double>& x,
203  DenseComplexMatrix& jacobian_matrix,
204  Vector<std::complex<double> >& transformed_x)
205  {
206  throw OomphLibError("AxisAlignedPMLElements produce diagonal matrices,"
207  "use the diagonal version of this function instead",
208  OOMPH_CURRENT_FUNCTION,
209  OOMPH_EXCEPTION_LOCATION);
210  }
211 
212  /// \short Disable pml. Ensures the PML-ification in all directions
213  /// has been deactivated
214  virtual void disable_pml()
215  {
216  // Disable base class attributes
218 
219  // Loop over the entries in Pml_direction_active and deactivate the
220  // PML in this direction
221  for (unsigned direction=0;direction<DIM;direction++)
222  {
223  // Disable the PML in this direction
224  Pml_direction_active[direction]=false;
225  }
226  } // End of disable_pml
227 
228  /// \short Enable pml. Specify the coordinate direction along which
229  /// pml boundary is constant, as well as the coordinate
230  /// along the dimension for the interface between the physical and artificial
231  /// domains and the coordinate for the outer boundary.
232  /// All of these are used to adjust the perfectly matched layer
233  /// mechanism. Needs to be called separately for each pml-ified direction
234  /// (if needed -- e.g. in corner elements)
235  virtual void enable_pml(const int& direction,
236  const double& pml_inner_boundary,
237  const double& pml_outer_boundary)
238  {
240  Pml_direction_active[direction] = true;
241  Pml_inner_boundary[direction] = pml_inner_boundary;
242  Pml_outer_boundary[direction] = pml_outer_boundary;
243  }
244 
245  virtual void enable_pml(const int& direction,
246  const double& pml_inner_boundary,
247  const double& pml_outer_boundary,
248  UniaxialPMLMapping* pml_mapping_pt)
249  {
250  enable_pml(direction, pml_inner_boundary, pml_outer_boundary);
251  Pml_mapping_pt = pml_mapping_pt;
252  }
253 
254  /// Return a pointer to the PML Mapping object
255  UniaxialPMLMapping* &pml_mapping_pt() {return Pml_mapping_pt;}
256 
257  /// Return a pointer to the PML Mapping object (const version)
258  UniaxialPMLMapping* const &pml_mapping_pt() const {return Pml_mapping_pt;}
259 
260  /// Vector which points from the inner boundary to x
261  inline double nu(const Vector<double>& x, const unsigned& i) const
262  {
263  return x[i] - this->Pml_inner_boundary[i];
264  }
265 
266  /// Vector which points from the inner boundary to x
267  void nu(const Vector<double>& x, Vector<double> nu_vec) const
268  {
269  for(unsigned i=0; i<DIM; i++)
270  {
271  nu_vec[i] = nu(x, i);
272  }
273  }
274 
275  /// Vector which points from the inner boundary to x
276  inline double delta(const unsigned& i) const
277  {
278  return this->Pml_outer_boundary[i] - this->Pml_inner_boundary[i];
279  }
280 
281  /// Vector which points from the inner boundary to x
282  void delta(const Vector<double>& x, Vector<double> delta) const
283  {
284  for(unsigned i=0; i<DIM; i++)
285  {
286  delta[i] = this->Pml_outer_boundary[i] - this->Pml_inner_boundary[i];
287  }
288  }
289 
290 protected:
291 
292  /// \short Coordinate direction along which pml boundary is constant;
293  /// alternatively: coordinate direction in which coordinate stretching
294  /// is performed.
295  std::vector<bool> Pml_direction_active;
296 
297  /// \short Coordinate of inner pml boundary
298  /// (Storage is provided for any coordinate
299  /// direction; only the entries for "active" directions is used.)
301 
302  /// \short Coordinate of outer pml boundary
303  /// (Storage is provided for any coordinate
304  /// direction; only the entries for "active" directions is used.)
306 
308 };
309 
311 {
312 
313 public:
314 
315  ///
316  virtual void pml_transformation_jacobian(
317  const unsigned& ipt,
318  const Vector<double>& s,
319  const Vector<double>& x,
320  DenseComplexMatrix& jacobian) = 0;
321 
322  ///
323  virtual void pml_transformation_jacobian(
324  const unsigned& ipt,
325  const Vector<double>& s,
326  const Vector<double>& x,
327  DenseComplexMatrix& jacobian_matrix,
328  Vector<std::complex<double> >& transformed_x) = 0;
329 
330  //
331  void radial_to_cartesian_jacobian(
332  const double& r,
333  const double& theta,
334  const std::complex<double>& transformed_r,
335  const std::complex<double>& dtransformed_r_dr,
336  DenseComplexMatrix& cartesian_jacobian) const;
337 
338  //
339  void radial_to_cartesian_jacobian(
340  const double& r,
341  const double& theta,
342  const std::complex<double>& rt,
343  const DenseComplexMatrix& radial_jacobian,
344  DenseComplexMatrix& cartesian_jacobian) const;
345 
346  /// \short get the Jacobian of the mapping from transformed r to the radial
347  /// through-the-pml coordinate. Also returns the transformed_r at this point too
348  /// as it is required for the transformation to cartesian coordinates
349  virtual void radial_transformation_jacobian(
350  const double& nu,
351  const double& delta,
352  std::complex<double>& transformed_r,
353  std::complex<double>& dtransformed_r_dr) const = 0;
354 
355  //
356  virtual double radius(const Vector<double>& s, const Vector<double>& x) = 0;
357 
358  //
359  virtual double nu(const Vector<double>& s, const Vector<double>& x) = 0;
360 
361  //
362  virtual double theta(const Vector<double>& s, const Vector<double>& x) = 0;
363 
364  virtual double delta() = 0;
365 };
366 
367 
369 {
370 public:
371 
372  /// Constructor
374  Pml_inner_radius(0.0),
375  Pml_outer_radius(0.0),
376  Origin(2, 0.0),
377  Pml_mapping_pt(0)
378  {}
379 
380  /// Enable pml. Specify the inner and outer radius of PML and the origin
381  virtual void enable_pml(
382  const double& inner_pml_radius,
383  const double& outer_pml_radius,
384  const Vector<double>& origin,
385  UniaxialPMLMapping* pml_mapping_pt)
386  {
388  Pml_inner_radius = inner_pml_radius;
389  Pml_outer_radius = outer_pml_radius;
390  Origin = origin;
391  Pml_mapping_pt = pml_mapping_pt;
392  }
393 
394  double radius(const Vector<double>& s, const Vector<double>& x)
395  {
396  return sqrt(std::pow(x[0]-Origin[0],2) + std::pow(x[1]-Origin[1],2));
397  }
398 
399  /// Coordinate which goes through the PML
400  double nu(const Vector<double>& s, const Vector<double>& x)
401  {
402  return nu(radius(s, x));
403  }
404 
405  /// Coordinate which goes through the PML
406  double nu(const double& r)
407  {
408  return r - Pml_inner_radius;
409  }
410 
411  /// Thickness of PML
412  double delta() { return Pml_outer_radius - Pml_inner_radius; }
413 
414  /// Angle relative to origin
415  double theta(const Vector<double>& x)
416  {
417  return atan2(x[1]-Origin[1], x[0]-Origin[0]);
418  }
419 
420  /// \short get the Jacobian of the mapping from transformed r to the radial
421  /// through-the-pml coordinate. Also returns the transformed_r at this point too
422  /// as it is required for the transformation to cartesian coordinates
424  const double& nu,
425  const double& delta,
426  std::complex<double>& transformed_r,
427  std::complex<double>& dtransformed_r_dr)
428  {
429  const double k = this->wavenumber();
430  transformed_r = Pml_inner_radius
431  + Pml_mapping_pt->transformed_nu(nu, delta, k);
432  dtransformed_r_dr = Pml_mapping_pt->dtransformed_nu_dnu(nu, delta, k);
433  }
434 
435 protected:
436 
437  /// \short Coordinate direction along which pml boundary is constant;
438  /// alternatively: coordinate direction in which coordinate stretching
439  /// is performed.
441 
442  /// \short Coordinate of inner pml boundary
443  /// (Storage is provided for any coordinate
444  /// direction; only the entries for "active" directions is used.)
446 
447  /// \short Coordinate of outer pml boundary
448  /// (Storage is provided for any coordinate
449  /// direction; only the entries for "active" directions is used.)
451 
452  // A uniaxial PML mapping used to transform the radial coordinate
454 };
455 
456 
458 {
459 public:
460 
461  /// Constructor
463  Nu_s_index(0),
464  Nu_at_s_min(0.0),
465  Nu_at_s_max(0.0),
466  Theta_s_index(0),
467  Theta_at_s_min(0.0),
468  Theta_at_s_max(0.0),
469  Pml_inner_radius(0.0),
470  Pml_outer_radius(0.0)
471  {}
472 
473  /// Constructor
475  unsigned nu_s_index,
476  double nu_at_s_min,
477  double nu_at_s_max,
478  unsigned theta_s_index,
479  double theta_at_s_min,
480  double theta_at_s_max,
481  double pml_inner_radius,
482  double pml_outer_radius) :
483  Nu_s_index(nu_s_index),
484  Nu_at_s_min(nu_at_s_min),
485  Nu_at_s_max(nu_at_s_max),
486  Theta_s_index(theta_s_index),
487  Theta_at_s_min(theta_at_s_min),
488  Theta_at_s_max(theta_at_s_max),
489  Pml_inner_radius(pml_inner_radius),
490  Pml_outer_radius(pml_outer_radius)
491  {}
492 
493  /// Enable pml. Specify the inner and outer radius of PML and the origin
494  virtual void enable_pml(const double& inner_pml_radius,
495  const double& outer_pml_radius, const Vector<double>& origin)
496  {
498  }
499 
500  virtual double s_min();
501 
502  virtual double s_max();
503 
504  /// Coordinate which goes through the PML in terms of local coordinate
505  double nu(const Vector<double>& s, const Vector<double>& x)
506  {
507  return (s[Nu_s_index]-s_min())/(s_max()-s_min())*(Nu_at_s_max-Nu_at_s_min)
508  + Nu_at_s_min;
509  }
510 
511  /// Thickness of PML
512  double delta() { return Pml_outer_radius - Pml_inner_radius; }
513 
514  /// Angle relative to origin
515  double theta(const Vector<double>& s, const Vector<double>& x)
516  {
517  return (s[Theta_s_index]-s_min())/(s_max()-s_min())
518  *(Theta_at_s_max - Theta_at_s_min)
519  + Theta_at_s_min;
520  }
521 
522  /// \short get the Jacobian of the mapping from transformed r to the radial
523  /// through-the-pml coordinate. Also returns the transformed_r at this point too
524  /// as it is required for the transformation to cartesian coordinates
526  const double& nu,
527  const double& delta,
528  std::complex<double>& transformed_r,
529  std::complex<double>& dtransformed_r_dr)
530  {
531  const double k = this->wavenumber();
532  transformed_r = Pml_inner_radius
533  + Pml_mapping_pt->transformed_nu(nu, delta, k);
534  dtransformed_r_dr = Pml_mapping_pt->dtransformed_nu_dnu(nu, delta, k);
535  }
536 
537 protected:
538 
539  /// \short Index of local coordinate which nu (through the PML coordinate) is
540  /// parametrised by
541  unsigned Nu_s_index;
542 
543  /// Value of nu at the minimum value of local coordinate
544  double Nu_at_s_min;
545 
546  /// Value of nu at the maximum value of local coordinate
547  double Nu_at_s_max;
548 
549  /// Index of local coordinate which theta is parametrised by
550  unsigned Theta_s_index;
551 
552  /// Value of theta at the minimum value of local coordinate
554 
555  /// Value of theta at the maximum value of local coordinate
557 
558  /// \short Value of radius at inner PML boundary
560 
561  /// \short Value of radius at outer PML boundary
563 
564  // A uniaxial PML mapping used to transform the radial coordinate
566 };
567 
568 
570 {
571 public:
572 
573  /// Constructor
575  Nu_s_index(0),
576  Nu_at_s_min(0.0),
577  Nu_at_s_max(0.0),
578  Pml_mapping_pt(0)
579  {}
580 
581  /// Constructor
583  const unsigned nu_s_index,
584  const double nu_at_s_min,
585  const double nu_at_s_max) :
586  Nu_s_index(nu_s_index),
587  Nu_at_s_min(nu_at_s_min),
588  Nu_at_s_max(nu_at_s_max),
589  Pml_mapping_pt(0)
590  {}
591 
592  ///
593  virtual void pml_transformation_jacobian(
594  const unsigned& ipt,
595  const Vector<double>& s,
596  const Vector<double>& x,
597  DenseComplexMatrix& jacobian);
598 
599  ///
600  virtual void pml_transformation_jacobian(
601  const unsigned& ipt,
602  const Vector<double>& s,
603  const Vector<double>& x,
604  DenseComplexMatrix& jacobian_matrix,
605  Vector<std::complex<double> >& transformed_x);
606 
607  /// Enable pml. Set the pointer to a PML mapping function
608  virtual void enable_pml(UniaxialPMLMapping* pml_mapping_pt)
609  {
611  pml_mapping_pt = Pml_mapping_pt;
612  }
613 
614  /// Coordinate which goes through the PML in terms of local coordinate
615  double nu(const Vector<double>& s)
616  {
617  return (s[Nu_s_index]-s_min())/(s_max()-s_min())*(Nu_at_s_max-Nu_at_s_min)
618  + Nu_at_s_min;
619  }
620 
621  //
622  void assemble_conformal_jacobian(
623  const Vector<double>& p,
624  const Vector<double>& dx_inner_dacross,
625  const Vector<double>& dp_dacross,
626  const double& nu,
627  const std::complex<double>& tnu,
628  const std::complex<double>& dtnu_dnu,
629  DenseComplexMatrix& mapping_jacobian);
630 
631  //
632  unsigned nu_s_index() const { return Nu_s_index; }
633 
634  //
635  unsigned across_s_index() const { return (Nu_s_index+1) % 2; }
636 
637 protected:
638 
639  // Extract various vectors which characterise the PML and its geometry
640  void get_pml_properties(const Vector<double>& s,
641  Vector<double>& x_inner,
642  Vector<double>& x_outer,
643  Vector<double>& p,
644  Vector<double>& dx_inner_dacross,
645  Vector<double>& dp_dacross,
646  double& delta);
647 
648  /// \short Index of local coordinate which nu (through the PML coordinate) is
649  /// parametrised by
650  unsigned Nu_s_index;
651 
652  /// Value of nu at the minimum value of local coordinate
653  double Nu_at_s_min;
654 
655  /// Value of nu at the maximum value of local coordinate
656  double Nu_at_s_max;
657 
659 };
660 
662 {
663 public:
664 
665  /// Constructor
667  {}
668 
669  /// Constructor
671  const unsigned nu_s_index,
672  const double nu_at_s_min,
673  const double nu_at_s_max) :
674  Conformal2DPMLElement(nu_s_index, nu_at_s_min, nu_at_s_max)
675  {}
676 
677  /// Enable pml. Set the pointer to a PML mapping function
679  {
681  Tangentially_varying_pml_mapping_pt = pml_mapping_pt;
682  }
683 
684  ///
685  virtual void pml_transformation_jacobian(
686  const unsigned& ipt,
687  const Vector<double>& s,
688  const Vector<double>& x,
689  DenseComplexMatrix& jacobian);
690 
691  ///
692  virtual void pml_transformation_jacobian(
693  const unsigned& ipt,
694  const Vector<double>& s,
695  const Vector<double>& x,
696  DenseComplexMatrix& jacobian_matrix,
697  Vector<std::complex<double> >& transformed_x);
698 
699  //
700  void assemble_conformal_jacobian(
701  const Vector<double>& p,
702  const Vector<double>& dx_inner_dacross,
703  const Vector<double>& dp_dacross,
704  const double& nu,
705  const std::complex<double>& tnu,
706  const std::complex<double>& dtnu_dnu,
707  const std::complex<double>& dtnu_dacross,
708  DenseComplexMatrix& mapping_jacobian);
709 
710 protected:
711 
712  // Extract various vectors which characterise the PML and its geometry
713  void get_pml_properties(const double& s_across_the_pml,
714  Vector<double>& x_inner,
715  Vector<double>& x_outer,
716  Vector<double>& p,
717  Vector<double>& dx_inner_dacross,
718  Vector<double>& dp_dacross,
719  double& delta,
720  unsigned& across_the_pml_index,
721  unsigned& through_the_pml_index);
722 
724 };
725 
726 
729 {
730 public:
731 
732  /// Constructor
735  {}
736 
737  /// Constructor
739  const unsigned nu_s_index,
740  const double nu_at_s_min,
741  const double nu_at_s_max) :
742  TangentiallyVaryingConformal2DPMLElement(nu_s_index, nu_at_s_min,
743  nu_at_s_max)
744  {}
745 
746  /// Enable pml. Set the pointer to a PML mapping function
748  {
750  Tangentially_discontinuous_pml_mapping_pt = pml_mapping_pt;
751  }
752 
753  ///
754  virtual void pml_transformation_jacobian(
755  const unsigned& ipt,
756  const Vector<double>& s,
757  const Vector<double>& x,
758  DenseComplexMatrix& jacobian);
759 
760  ///
761  virtual void pml_transformation_jacobian(
762  const unsigned& ipt,
763  const Vector<double>& s,
764  const Vector<double>& x,
765  DenseComplexMatrix& jacobian_matrix,
766  Vector<std::complex<double> >& transformed_x);
767 
768  // Use this mode to hijack the assembly process to find rips
769  static bool Find_rips_mode;
770 
771  /// Information about a rip in two dimensions
772  struct TwoDimRip{
773  /// Position of onset of rip in local and global coordinates
774  FiniteElementPt ripped_element_pt;
775  double s_across;
776  double s_through;
777  double x;
778  double y;
779  std::complex<double> tnu;
780  // Factor which describes behaviour near rip through the PML
781  // - \frac{partial^2 u}{\partial \tilde\nu^2} / U at rip
782  std::complex<double> alpha;
783  // Factor which describes behaviour near rip across the PML
784  // - i \frac{partial^2 u}{\partial \tilde\nu^2}
785  // / (U'(1-\bar\nu) -\frac{\partial u}{\partial \zeta}) at rip
786  std::complex<double> beta;
787 
788  // Constructor with all parameters
789  TwoDimRip(FiniteElementPt Ripped_element_pt, const double& S_across,
790  const double& S_through, const double& X, const double& Y,
791  const std::complex<double> Tnu, const std::complex<double> Alpha,
792  const std::complex<double> Beta):
793  ripped_element_pt(Ripped_element_pt), s_across(S_across),
794  s_through(S_through), x(X), y(Y), tnu(Tnu), alpha(Alpha), beta(Beta)
795  { }
796  };
797 
798  // Holds information about all known rips, which we will use to inform our
799  // integration scheme
801 
802  /// Look for rips in the transformation and store in rips vector
803  void find_rips();
804 
805  /// Compute distance from rip to PML element edge
806  double distance_from_element_edge( const Vector<double>& x_inner,
807  const Vector<double>& x_outer, const Vector<double>& p,
808  const Vector<double>& r);
809 
810  /// \short Compute n'J^{-1}, which when applied to the untransformed
811  /// grad operator gives us the transformed normal derivative
812  void compute_transformed_normal_derivative(
813  const DenseComplexMatrix& J,
814  const Vector<double>& n,
815  Vector<std::complex<double> >& result);
816 
817  // You must overload this to do the normal things in your specific element
818  virtual void fill_in_contribution_to_jacobian_no_rips(
819  Vector<double> &residuals,
820  DenseMatrix<double> &jacobian, bool flag) = 0;
821 
822  // You must overload this and handle the rips in your specific element
823  virtual void fill_in_contribution_to_jacobian_with_rips(
824  Vector<double> &residuals,
825  DenseMatrix<double> &jacobian, bool flag) = 0;
826 
827  /// Add the element's contribution to its residual vector (wrapper)
829  {
830  if(this->Pml_is_enabled && !Disable_rip_integration)
831  {
832  // Use this mode to hijack the assembly process to find rips
833  if(Find_rips_mode)
834  {
835  find_rips();
836  return;
837  }
838 
839  //Call the generic residuals function with flag set to 0
840  //using a dummy matrix argument
841  fill_in_contribution_to_jacobian_with_rips(residuals,
843  }
844  else
845  {
846  //Call the generic residuals function with flag set to 0
847  //using a dummy matrix argument
848  fill_in_contribution_to_jacobian_no_rips(
850  }
851  }
852 
853  /// \short Add the element's contribution to its residual vector and
854  /// element Jacobian matrix (wrapper)
856  Vector<double> &residuals,
857  DenseMatrix<double> &jacobian)
858  {
859  if(this->Pml_is_enabled && !Disable_rip_integration)
860  {
861  // Use this mode to hijack the assembly process to find rips
862  if(Find_rips_mode)
863  {
864  find_rips();
865  return;
866  }
867  // Call the generic routine with the flag set to 1
868  fill_in_contribution_to_jacobian_with_rips(
869  residuals, jacobian, 1);
870  }
871  else
872  {
873  //Call the generic routine with the flag set to 1
874  fill_in_contribution_to_jacobian_no_rips(residuals, jacobian,1);
875  }
876  }
877 protected:
878  // Pretend that there is a rip at some point in the element to test that it has
879  // no effect. This is overridden by disable rip integration
881 
882  // Do not do the integration process which find and treats rips separately
884 
886 };
887 
888 }
889 
890 #endif
A Generalised Element class.
Definition: elements.h:76
void nu(const Vector< double > &x, Vector< double > nu_vec) const
Vector which points from the inner boundary to x.
Definition: pml_elements.h:267
unsigned Nu_s_index
Index of local coordinate which nu (through the PML coordinate) is parametrised by.
Definition: pml_elements.h:541
void delta(const Vector< double > &x, Vector< double > delta) const
Vector which points from the inner boundary to x.
Definition: pml_elements.h:282
double Theta_at_s_min
Value of theta at the minimum value of local coordinate.
Definition: pml_elements.h:553
double Pml_inner_radius
Value of radius at inner PML boundary.
Definition: pml_elements.h:559
FiniteElement * FiniteElementPt
Definition: pml_elements.h:48
virtual void radial_transformation_jacobian(const double &nu, const double &delta, std::complex< double > &transformed_r, std::complex< double > &dtransformed_r_dr)
get the Jacobian of the mapping from transformed r to the radial through-the-pml coordinate. Also returns the transformed_r at this point too as it is required for the transformation to cartesian coordinates
Definition: pml_elements.h:525
double Pml_outer_radius
Coordinate of inner pml boundary (Storage is provided for any coordinate direction; only the entries ...
Definition: pml_elements.h:445
TwoDimRip(FiniteElementPt Ripped_element_pt, const double &S_across, const double &S_through, const double &X, const double &Y, const std::complex< double > Tnu, const std::complex< double > Alpha, const std::complex< double > Beta)
Definition: pml_elements.h:789
double Nu_at_s_min
Value of nu at the minimum value of local coordinate.
Definition: pml_elements.h:653
virtual void pml_transformation_jacobian(const unsigned &ipt, const Vector< double > &s, const Vector< double > &x, DenseComplexMatrix &jacobian)
Definition: pml_elements.h:178
UniaxialPMLMapping * Pml_mapping_pt
Definition: pml_elements.h:307
cstr elem_len * i
Definition: cfortran.h:607
double radius(const Vector< double > &s, const Vector< double > &x)
Definition: pml_elements.h:394
virtual void disable_pml()
Disable pml.
Definition: pml_elements.h:77
A general Finite Element class.
Definition: elements.h:1274
double Nu_at_s_min
Value of nu at the minimum value of local coordinate.
Definition: pml_elements.h:544
double delta(const unsigned &i) const
Vector which points from the inner boundary to x.
Definition: pml_elements.h:276
double Nu_at_s_max
Value of nu at the maximum value of local coordinate.
Definition: pml_elements.h:656
double nu(const Vector< double > &s, const Vector< double > &x)
Coordinate which goes through the PML.
Definition: pml_elements.h:400
Vector< double > Pml_inner_boundary
Coordinate of inner pml boundary (Storage is provided for any coordinate direction; only the entries ...
Definition: pml_elements.h:300
virtual void enable_pml(TangentiallyVaryingConformalPMLMapping *pml_mapping_pt)
Enable pml. Set the pointer to a PML mapping function.
Definition: pml_elements.h:678
TangentiallyDiscontinuousConformalPMLMapping * Tangentially_discontinuous_pml_mapping_pt
Definition: pml_elements.h:885
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element&#39;s contribution to its residual vector (wrapper)
Definition: pml_elements.h:828
UniaxialPMLMapping *& pml_mapping_pt()
Return a pointer to the PML Mapping object.
Definition: pml_elements.h:255
Information about a rip in two dimensions.
Definition: pml_elements.h:772
double nu(const Vector< double > &s, const Vector< double > &x)
Coordinate which goes through the PML in terms of local coordinate.
Definition: pml_elements.h:505
virtual void enable_pml(const int &direction, const double &pml_inner_boundary, const double &pml_outer_boundary, UniaxialPMLMapping *pml_mapping_pt)
Definition: pml_elements.h:245
Conformal2DPMLElement()
Constructor.
Definition: pml_elements.h:574
double theta(const Vector< double > &x)
Angle relative to origin.
Definition: pml_elements.h:415
Base class for elements with pml capabilities.
Definition: pml_elements.h:65
AxisAlignedPMLElement()
Constructor.
Definition: pml_elements.h:165
virtual void enable_pml(TangentiallyDiscontinuousConformalPMLMapping *pml_mapping_pt)
Enable pml. Set the pointer to a PML mapping function.
Definition: pml_elements.h:747
static char t char * s
Definition: cfortran.h:572
unsigned Theta_s_index
Index of local coordinate which theta is parametrised by.
Definition: pml_elements.h:550
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) ...
Definition: pml_elements.h:855
double nu(const Vector< double > &s)
Coordinate which goes through the PML in terms of local coordinate.
Definition: pml_elements.h:615
bool Pml_is_enabled
Boolean indicating if element is used in pml mode.
Definition: pml_elements.h:153
unsigned across_s_index() const
Definition: pml_elements.h:635
unsigned nu_s_index() const
Definition: pml_elements.h:632
Conformal2DPMLElement(const unsigned nu_s_index, const double nu_at_s_min, const double nu_at_s_max)
Constructor.
Definition: pml_elements.h:582
GeneralisedElement GeneralisedElementTypedef
Definition: pml_elements.h:49
virtual ~PMLElementBase()
Virtual destructor.
Definition: pml_elements.h:74
AnnularFromLocalCoordinatePMLElement(unsigned nu_s_index, double nu_at_s_min, double nu_at_s_max, unsigned theta_s_index, double theta_at_s_min, double theta_at_s_max, double pml_inner_radius, double pml_outer_radius)
Constructor.
Definition: pml_elements.h:474
virtual void radial_transformation_jacobian(const double &nu, const double &delta, std::complex< double > &transformed_r, std::complex< double > &dtransformed_r_dr)
get the Jacobian of the mapping from transformed r to the radial through-the-pml coordinate. Also returns the transformed_r at this point too as it is required for the transformation to cartesian coordinates
Definition: pml_elements.h:423
double Nu_at_s_max
Value of nu at the maximum value of local coordinate.
Definition: pml_elements.h:547
std::vector< bool > Pml_direction_active
Coordinate direction along which pml boundary is constant; alternatively: coordinate direction in whi...
Definition: pml_elements.h:295
virtual void enable_pml()
Enable pml.
Definition: pml_elements.h:83
UniaxialPMLMapping *const & pml_mapping_pt() const
Return a pointer to the PML Mapping object (const version)
Definition: pml_elements.h:258
TangentiallyDiscontinuousConformal2DPMLElement(const unsigned nu_s_index, const double nu_at_s_min, const double nu_at_s_max)
Constructor.
Definition: pml_elements.h:738
double nu(const Vector< double > &x, const unsigned &i) const
Vector which points from the inner boundary to x.
Definition: pml_elements.h:261
double delta()
Thickness of PML.
Definition: pml_elements.h:412
TangentiallyVaryingConformal2DPMLElement(const unsigned nu_s_index, const double nu_at_s_min, const double nu_at_s_max)
Constructor.
Definition: pml_elements.h:670
virtual void enable_pml(UniaxialPMLMapping *pml_mapping_pt)
Enable pml. Set the pointer to a PML mapping function.
Definition: pml_elements.h:608
Vector< double > Pml_outer_boundary
Coordinate of outer pml boundary (Storage is provided for any coordinate direction; only the entries ...
Definition: pml_elements.h:305
double nu(const double &r)
Coordinate which goes through the PML.
Definition: pml_elements.h:406
virtual void enable_pml(const double &inner_pml_radius, const double &outer_pml_radius, const Vector< double > &origin, UniaxialPMLMapping *pml_mapping_pt)
Enable pml. Specify the inner and outer radius of PML and the origin.
Definition: pml_elements.h:381
virtual void pml_transformation_jacobian(const unsigned &ipt, const Vector< double > &s, const Vector< double > &x, DenseComplexMatrix &jacobian_matrix, Vector< std::complex< double > > &transformed_x)
Definition: pml_elements.h:199
TangentiallyVaryingConformalPMLMapping * Tangentially_varying_pml_mapping_pt
Definition: pml_elements.h:723
virtual double wavenumber() const
Definition: pml_elements.h:113
virtual void disable_pml()
Disable pml. Ensures the PML-ification in all directions has been deactivated.
Definition: pml_elements.h:214
Vector< double > Origin
Coordinate of outer pml boundary (Storage is provided for any coordinate direction; only the entries ...
Definition: pml_elements.h:450
unsigned Nu_s_index
Index of local coordinate which nu (through the PML coordinate) is parametrised by.
Definition: pml_elements.h:650
double Pml_outer_radius
Value of radius at outer PML boundary.
Definition: pml_elements.h:562
FiniteElementPt ripped_element_pt
Position of onset of rip in local and global coordinates.
Definition: pml_elements.h:774
double theta(const Vector< double > &s, const Vector< double > &x)
Angle relative to origin.
Definition: pml_elements.h:515
UniaxialPMLMapping * Pml_mapping_pt
Definition: pml_elements.h:658
virtual void enable_pml(const int &direction, const double &pml_inner_boundary, const double &pml_outer_boundary)
Enable pml. Specify the coordinate direction along which pml boundary is constant, as well as the coordinate along the dimension for the interface between the physical and artificial domains and the coordinate for the outer boundary. All of these are used to adjust the perfectly matched layer mechanism. Needs to be called separately for each pml-ified direction (if needed – e.g. in corner elements)
Definition: pml_elements.h:235
double Pml_inner_radius
Coordinate direction along which pml boundary is constant; alternatively: coordinate direction in whi...
Definition: pml_elements.h:440
PMLElementBase()
Constructor.
Definition: pml_elements.h:71
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
Class of matrices containing double complex, and stored as a DenseMatrix<complex<double> >...
double Theta_at_s_max
Value of theta at the maximum value of local coordinate.
Definition: pml_elements.h:556
virtual void enable_pml(const double &inner_pml_radius, const double &outer_pml_radius, const Vector< double > &origin)
Enable pml. Specify the inner and outer radius of PML and the origin.
Definition: pml_elements.h:494