30 #ifndef OOMPH_PML_ELEMENT_HEADER 31 #define OOMPH_PML_ELEMENT_HEADER 35 #include <oomph-lib-config.h> 56 template<
class ELEMENT>
64 template<
unsigned DIM>
89 virtual void pml_transformation_jacobian(
96 virtual void pml_transformation_jacobian(
101 Vector<std::complex<double> >& transformed_x) = 0;
110 virtual void values_to_be_pinned_on_outer_pml_boundary(
115 throw OomphLibError(
"PML elements must implement wavenumber()",
116 OOMPH_CURRENT_FUNCTION,
117 OOMPH_EXCEPTION_LOCATION);
123 static void compute_laplace_matrix_and_det(
126 std::complex<double>& jacobian_det);
131 static void compute_laplace_matrix_and_det(
134 std::complex<double>& jacobian_det);
139 static void compute_laplace_matrix_and_det(
142 std::complex<double>& jacobian_det);
145 static void compute_jacobian_inverse_and_det(
148 std::complex<double>& jacobian_det);
159 template<
unsigned DIM>
166 Pml_direction_active(DIM,false),
167 Pml_inner_boundary(DIM,0.0),
168 Pml_outer_boundary(DIM,0.0)
172 virtual void pml_transformation_jacobian(
184 throw OomphLibError(
"AxisAlignedPMLElements produce diagonal matrices," 185 "use the diagonal version of this function instead",
186 OOMPH_CURRENT_FUNCTION,
187 OOMPH_EXCEPTION_LOCATION);
191 virtual void pml_transformation_jacobian(
196 Vector<std::complex<double> >& transformed_x);
204 Vector<std::complex<double> >& transformed_x)
206 throw OomphLibError(
"AxisAlignedPMLElements produce diagonal matrices," 207 "use the diagonal version of this function instead",
208 OOMPH_CURRENT_FUNCTION,
209 OOMPH_EXCEPTION_LOCATION);
221 for (
unsigned direction=0;direction<DIM;direction++)
224 Pml_direction_active[direction]=
false;
236 const double& pml_inner_boundary,
237 const double& pml_outer_boundary)
240 Pml_direction_active[direction] =
true;
241 Pml_inner_boundary[direction] = pml_inner_boundary;
242 Pml_outer_boundary[direction] = pml_outer_boundary;
246 const double& pml_inner_boundary,
247 const double& pml_outer_boundary,
250 enable_pml(direction, pml_inner_boundary, pml_outer_boundary);
251 Pml_mapping_pt = pml_mapping_pt;
263 return x[
i] - this->Pml_inner_boundary[
i];
269 for(
unsigned i=0;
i<DIM;
i++)
271 nu_vec[
i] = nu(x,
i);
276 inline double delta(
const unsigned&
i)
const 278 return this->Pml_outer_boundary[
i] - this->Pml_inner_boundary[
i];
284 for(
unsigned i=0;
i<DIM;
i++)
286 delta[
i] = this->Pml_outer_boundary[
i] - this->Pml_inner_boundary[
i];
316 virtual void pml_transformation_jacobian(
323 virtual void pml_transformation_jacobian(
328 Vector<std::complex<double> >& transformed_x) = 0;
331 void radial_to_cartesian_jacobian(
334 const std::complex<double>& transformed_r,
335 const std::complex<double>& dtransformed_r_dr,
339 void radial_to_cartesian_jacobian(
342 const std::complex<double>& rt,
349 virtual void radial_transformation_jacobian(
352 std::complex<double>& transformed_r,
353 std::complex<double>& dtransformed_r_dr)
const = 0;
364 virtual double delta() = 0;
374 Pml_inner_radius(0.0),
375 Pml_outer_radius(0.0),
382 const double& inner_pml_radius,
383 const double& outer_pml_radius,
388 Pml_inner_radius = inner_pml_radius;
389 Pml_outer_radius = outer_pml_radius;
391 Pml_mapping_pt = pml_mapping_pt;
396 return sqrt(std::pow(x[0]-Origin[0],2) + std::pow(x[1]-Origin[1],2));
402 return nu(radius(s, x));
406 double nu(
const double& r)
408 return r - Pml_inner_radius;
412 double delta() {
return Pml_outer_radius - Pml_inner_radius; }
417 return atan2(x[1]-Origin[1], x[0]-Origin[0]);
426 std::complex<double>& transformed_r,
427 std::complex<double>& dtransformed_r_dr)
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);
469 Pml_inner_radius(0.0),
470 Pml_outer_radius(0.0)
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)
500 virtual double s_min();
502 virtual double s_max();
507 return (s[Nu_s_index]-s_min())/(s_max()-s_min())*(Nu_at_s_max-Nu_at_s_min)
512 double delta() {
return Pml_outer_radius - Pml_inner_radius; }
517 return (s[Theta_s_index]-s_min())/(s_max()-s_min())
518 *(Theta_at_s_max - Theta_at_s_min)
528 std::complex<double>& transformed_r,
529 std::complex<double>& dtransformed_r_dr)
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);
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),
593 virtual void pml_transformation_jacobian(
600 virtual void pml_transformation_jacobian(
605 Vector<std::complex<double> >& transformed_x);
611 pml_mapping_pt = Pml_mapping_pt;
617 return (s[Nu_s_index]-s_min())/(s_max()-s_min())*(Nu_at_s_max-Nu_at_s_min)
622 void assemble_conformal_jacobian(
627 const std::complex<double>& tnu,
628 const std::complex<double>& dtnu_dnu,
671 const unsigned nu_s_index,
672 const double nu_at_s_min,
673 const double nu_at_s_max) :
681 Tangentially_varying_pml_mapping_pt = pml_mapping_pt;
685 virtual void pml_transformation_jacobian(
692 virtual void pml_transformation_jacobian(
697 Vector<std::complex<double> >& transformed_x);
700 void assemble_conformal_jacobian(
705 const std::complex<double>& tnu,
706 const std::complex<double>& dtnu_dnu,
707 const std::complex<double>& dtnu_dacross,
713 void get_pml_properties(
const double& s_across_the_pml,
720 unsigned& across_the_pml_index,
721 unsigned& through_the_pml_index);
739 const unsigned nu_s_index,
740 const double nu_at_s_min,
741 const double nu_at_s_max) :
750 Tangentially_discontinuous_pml_mapping_pt = pml_mapping_pt;
754 virtual void pml_transformation_jacobian(
761 virtual void pml_transformation_jacobian(
766 Vector<std::complex<double> >& transformed_x);
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)
812 void compute_transformed_normal_derivative(
815 Vector<std::complex<double> >& result);
818 virtual void fill_in_contribution_to_jacobian_no_rips(
823 virtual void fill_in_contribution_to_jacobian_with_rips(
830 if(this->Pml_is_enabled && !Disable_rip_integration)
841 fill_in_contribution_to_jacobian_with_rips(residuals,
848 fill_in_contribution_to_jacobian_no_rips(
859 if(this->Pml_is_enabled && !Disable_rip_integration)
868 fill_in_contribution_to_jacobian_with_rips(
869 residuals, jacobian, 1);
874 fill_in_contribution_to_jacobian_no_rips(residuals, jacobian,1);
A Generalised Element class.
void nu(const Vector< double > &x, Vector< double > nu_vec) const
Vector which points from the inner boundary to x.
unsigned Nu_s_index
Index of local coordinate which nu (through the PML coordinate) is parametrised by.
void delta(const Vector< double > &x, Vector< double > delta) const
Vector which points from the inner boundary to x.
double Theta_at_s_min
Value of theta at the minimum value of local coordinate.
double Pml_inner_radius
Value of radius at inner PML boundary.
FiniteElement * FiniteElementPt
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
double Pml_outer_radius
Coordinate of inner pml boundary (Storage is provided for any coordinate direction; only the entries ...
AnnularFromLocalCoordinatePMLElement()
Constructor.
virtual void pml_transformation_jacobian(const unsigned &ipt, const Vector< double > &s, const Vector< double > &x, DenseComplexMatrix &jacobian)
UniaxialPMLMapping * Pml_mapping_pt
double radius(const Vector< double > &s, const Vector< double > &x)
virtual void disable_pml()
Disable pml.
A general Finite Element class.
double Nu_at_s_min
Value of nu at the minimum value of local coordinate.
double delta(const unsigned &i) const
Vector which points from the inner boundary to x.
double nu(const Vector< double > &s, const Vector< double > &x)
Coordinate which goes through the PML.
Vector< double > Pml_inner_boundary
Coordinate of inner pml boundary (Storage is provided for any coordinate direction; only the entries ...
UniaxialPMLMapping *& pml_mapping_pt()
Return a pointer to the PML Mapping object.
double nu(const Vector< double > &s, const Vector< double > &x)
Coordinate which goes through the PML in terms of local coordinate.
virtual void enable_pml(const int &direction, const double &pml_inner_boundary, const double &pml_outer_boundary, UniaxialPMLMapping *pml_mapping_pt)
UniaxialPMLMapping * Pml_mapping_pt
double theta(const Vector< double > &x)
Angle relative to origin.
Base class for elements with pml capabilities.
double delta()
Thickness of PML.
AxisAlignedPMLElement()
Constructor.
unsigned Theta_s_index
Index of local coordinate which theta is parametrised by.
bool Pml_is_enabled
Boolean indicating if element is used in pml mode.
GeneralisedElement GeneralisedElementTypedef
virtual ~PMLElementBase()
Virtual destructor.
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.
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
double Nu_at_s_max
Value of nu at the maximum value of local coordinate.
std::vector< bool > Pml_direction_active
Coordinate direction along which pml boundary is constant; alternatively: coordinate direction in whi...
virtual void enable_pml()
Enable pml.
UniaxialPMLMapping *const & pml_mapping_pt() const
Return a pointer to the PML Mapping object (const version)
double nu(const Vector< double > &x, const unsigned &i) const
Vector which points from the inner boundary to x.
double delta()
Thickness of PML.
Vector< double > Pml_outer_boundary
Coordinate of outer pml boundary (Storage is provided for any coordinate direction; only the entries ...
double nu(const double &r)
Coordinate which goes through the PML.
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.
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)
virtual double wavenumber() const
virtual void disable_pml()
Disable pml. Ensures the PML-ification in all directions has been deactivated.
Vector< double > Origin
Coordinate of outer pml boundary (Storage is provided for any coordinate direction; only the entries ...
double Pml_outer_radius
Value of radius at outer PML boundary.
AnnularFromCartesianPMLElement()
Constructor.
double theta(const Vector< double > &s, const Vector< double > &x)
Angle relative to origin.
UniaxialPMLMapping * Pml_mapping_pt
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)
double Pml_inner_radius
Coordinate direction along which pml boundary is constant; alternatively: coordinate direction in whi...
PMLElementBase()
Constructor.
static DenseMatrix< double > Dummy_matrix
Empty dense matrix used as a dummy argument to combined residual and jacobian functions in the case w...
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.
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.