28#ifndef OOMPH_HELMHOLTZ_BC_ELEMENTS_HEADER
29#define OOMPH_HELMHOLTZ_BC_ELEMENTS_HEADER
33#include <oomph-lib-config.h>
40#include "oomph_crbond_bessel.h"
55 namespace Hankel_functions_for_helmholtz_problem
64 Vector<std::complex<double>>& h,
69 CRBond_Bessel::bessjyna(
76 <<
" rather than " <<
n <<
" Bessel functions.\n";
81 for (
unsigned i = 0;
i <
n;
i++)
83 h[
i] = std::complex<double>(
jn[
i],
yn[
i]);
96 const std::complex<double>& x,
97 Vector<std::complex<double>>& h,
116 CRBond_Bessel::cbessjyna(
129 <<
" Bessel functions.\n";
140 for (
unsigned i = 0;
i <
n;
i++)
165 template<
class ELEMENT>
179 "Don't call empty constructor for HelmholtzBCElementBase",
203 const unsigned&
i)
const
326 std::complex<double>
dphi_dn(0.0, 0.0);
397 error_stream <<
"a_coeff_pos and a_coeff_neg must have "
398 <<
"the same size. \n";
405 const std::complex<double> I(0.0, 1.0);
422 for (
unsigned i = 0;
i <
n;
i++)
433 for (
unsigned i = 0;
i < (this->
Dim - 1);
i++)
449 std::complex<double> interpolated_u(0.0, 0.0);
455 for (
unsigned i = 0;
i < this->
Dim;
i++)
462 const std::complex<double>
u_value(
484 for (
unsigned i = 0;
i <
n;
i++)
490 for (
unsigned i = 1;
i <
n;
i++)
532 for (
unsigned j = 0;
j < (
Dim - 1);
j++)
560 template<
class ELEMENT>
623 std::map<FiniteElement*, Vector<std::map<unsigned, std::complex<double>>>>
637 template<
class ELEMENT>
694 const unsigned&
flag)
707 throw OomphLibError(
"Pointer to outer radius hasn't been set!",
742 for (
unsigned i = 0;
i < (this->
Dim - 1);
i++)
763 std::complex<double> interpolated_u(0.0, 0.0);
764 std::complex<double>
du_dS(0.0, 0.0);
771 const std::complex<double>
u_value(
800 if (local_eqn_real >= 0)
805 (0.5 / R) * interpolated_u.real()) *
843 (0.5 / R) * interpolated_u.imag()) *
892 if (local_eqn_real >= 0)
897 (
k * interpolated_u.imag() +
898 (0.5 / R) * interpolated_u.real()) *
900 ((0.125 / (
k * R * R)) * interpolated_u.imag()) *
test[
l] * W;
944 (-
k * interpolated_u.real() +
945 (0.5 / R) * interpolated_u.imag()) *
947 ((-0.125 / (
k * R * R)) * interpolated_u.real()) *
test[
l] * W;
1000 if (local_eqn_real >= 0)
1004 ((
k * (1 + 0.125 / (
k *
k * R * R))) * interpolated_u.imag() +
1005 (0.5 / R - 0.125 / (
k *
k * R * R * R)) *
1006 interpolated_u.real()) *
1010 ((-0.5 /
k) *
du_dS.imag() +
1011 (0.5 / (
k *
k * R)) *
du_dS.real()) *
1029 (0.5 / R - 0.125 / (
k *
k * R * R * R)) *
psi[
l2] *
1057 ((-
k * (1 + 0.125 / (
k *
k * R * R))) * interpolated_u.real() +
1058 (0.5 / R - 0.125 / (
k *
k * R * R * R)) *
1059 interpolated_u.imag()) *
1063 ((0.5 /
k) *
du_dS.real() +
1064 (0.5 / (
k *
k * R)) *
du_dS.imag()) *
1092 (0.5 / R - 0.125 / (
k *
k * R * R * R)) *
psi[
l2] *
1119 template<
class ELEMENT>
1158 std::map<
unsigned, std::complex<double>>&
d_gamma_con);
1183 for (
unsigned e = 0;
e <
nel;
e++)
1187 for (
unsigned j = 0;
j <
nnod;
j++)
1192 if (!(
nod_pt->is_a_copy()))
1200 for (
unsigned j = 0;
j <
nnod;
j++)
1215 for (std::set<Node*>::iterator
it =
node_set.begin();
1231 const unsigned&
flag)
1265 for (
unsigned i = 0;
i < (this->
Dim - 1);
i++)
1291 if (local_eqn_real >= 0)
1458 template<
class ELEMENT>
1463 std::map<
unsigned, std::complex<double>>&
d_gamma_con)
1466 const std::complex<double> I(0.0, 1.0);
1486 gamma_con = std::complex<double>(0.0, 0.0);
1494 for (
unsigned i = 0;
i < (this->Dim - 1);
i++)
1510 std::complex<double> interpolated_u(0.0, 0.0);
1516 for (
unsigned i = 0;
i < this->Dim;
i++)
1590 namespace ToleranceForHelmholtzOuterBoundary
1603 namespace ToleranceForHelmholtzOuterBoundary
1620 template<
class ELEMENT>
1629 error_stream <<
"a_coeff_pos and a_coeff_neg must have "
1630 <<
"the same size. \n";
1640 for (
unsigned i = 0;
i <
n;
i++)
1647 unsigned nel = this->nelement();
1648 for (
unsigned e = 0;
e <
nel;
e++)
1659 for (
unsigned i = 0;
i <
n;
i++)
1673 template<
class ELEMENT>
1679 unsigned nel = this->nelement();
1680 for (
unsigned e = 0;
e <
nel;
e++)
1684 for (
unsigned j = 0;
j <
nnod;
j++)
1694 double r =
sqrt(x[0] * x[0] + x[1] * x[1]);
1697 if (Outer_radius == 0.0)
1699 throw OomphLibError(
"Outer radius for DtN BC must not be zero!",
1704 if (std::fabs((
r - this->Outer_radius) / Outer_radius) >
1708 error_stream <<
"Node at " << x[0] <<
" " << x[1] <<
" has radius "
1709 <<
r <<
" which does not "
1710 <<
" agree with \nspecified outer radius "
1711 << this->Outer_radius <<
" within relative tolerance "
1713 <<
".\nYou can adjust the tolerance via\n"
1714 <<
"ToleranceForHelmholtzOuterBoundary::Tol\n"
1715 <<
"or recompile without PARANOID.\n";
1730 sqrt(
dynamic_cast<ELEMENT*
>(
el_pt->bulk_element_pt())->k_squared());
1736 Nfourier_terms, Outer_radius *
k,
h_a,
hp_a);
1737 for (
unsigned i = 0;
i < Nfourier_terms;
i++)
1743 unsigned nel = this->nelement();
1744 for (
unsigned e = 0;
e <
nel;
e++)
1749 this->element_pt(
e));
1756 std::complex<double>(0.0, 0.0));
1784 for (
unsigned nn = 0;
nn < Nfourier_terms;
nn++)
1792 this->element_pt(
ee));
1795 eel_pt->compute_gamma_contribution(
1799 eel_pt->compute_gamma_contribution(
1810 l,
eel_pt->u_index_helmholtz().real());
1821 l,
eel_pt->u_index_helmholtz().imag());
1840 l,
eel_pt->u_index_helmholtz().real());
1851 l,
eel_pt->u_index_helmholtz().imag());
1876 template<
class ELEMENT>
1884 ELEMENT*
elem_pt =
new ELEMENT;
1893 "work correctly if nodes are hanging\n",
1894 "HelmholtzBCElementBase::Constructor",
1930 "Bulk element must inherit from HelmholtzEquations.";
1932 "Nodes are one dimensional, but cannot cast the bulk element to\n";
1934 error_string +=
"If you desire this functionality, you must "
1935 "implement it yourself\n";
1958 "Bulk element must inherit from HelmholtzEquations.";
1960 "Nodes are two dimensional, but cannot cast the bulk element to\n";
1962 error_string +=
"If you desire this functionality, you must "
1963 "implement it yourself\n";
1986 "Bulk element must inherit from HelmholtzEquations.";
1987 error_string +=
"Nodes are three dimensional, but cannot cast the "
1988 "bulk element to\n";
1990 error_string +=
"If you desire this functionality, you must "
1991 "implement it yourself\n";
2008 <<
". It should be 1,2, or 3!" << std::endl;
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
FaceElements are elements that coincide with the faces of higher-dimensional "bulk" elements....
int & face_index()
Index of the face (a number that uniquely identifies the face in the element)
void outer_unit_normal(const Vector< double > &s, Vector< double > &unit_normal) const
Compute outer unit normal at the specified local coordinate.
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,...
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.
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...
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
double J_eulerian(const Vector< double > &s) const
Return the Jacobian of mapping from local to global coordinates at local position s....
FaceGeometry class definition: This policy class is used to allow construction of face elements that ...
A general Finite Element class.
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
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...
virtual void output(std::ostream &outfile)
Output the element data — typically the values at the nodes in a format suitable for post-processing.
double size() const
Calculate the size of the element (length, area, volume,...) in Eulerian computational coordinates....
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...
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
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.
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
unsigned nnode() const
Return the number of nodes.
double nodal_position(const unsigned &n, const unsigned &i) const
Return the i-th coordinate at local node n. If the node is hanging, the appropriate interpolation is ...
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...
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
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...
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....
unsigned nexternal_data() const
Return the number of external data objects.
unsigned long eqn_number(const unsigned &ieqn_local) const
Return the global equation number corresponding to the ieqn_local-th local equation number.
static DenseMatrix< double > Dummy_matrix
Empty dense matrix used as a dummy argument to combined residual and jacobian functions in the case w...
int external_local_eqn(const unsigned &i, const unsigned &j)
Return the local equation number corresponding to the j-th value stored at the i-th external data.
unsigned add_external_data(Data *const &data_pt, const bool &fd=true)
Add a (pointer to an) external data object to the element and return its index (i....
Absorbing BC element for approximation imposition of Sommerfeld radiation condition.
void fill_in_generic_residual_contribution_helmholtz_abc(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Compute the element's residual vector and the ( Jacobian matrix. Overloaded version,...
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.
unsigned * ABC_order_pt
Pointer to order of absorbing boundary condition.
double * Outer_radius_pt
Pointer to radius of outer boundary (must be a circle!)
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector.
HelmholtzAbsorbingBCElement(FiniteElement *const &bulk_el_pt, const int &face_index)
Construct element from specification of bulk element and face index.
double *& outer_radius_pt()
Get pointer to radius of outer boundary (must be a cirle)
unsigned *& abc_order_pt()
Pointer to order of absorbing boundary condition.
A class for elements that allow the approximation of the Sommerfeld radiation BC. The element geometr...
double test_only(const Vector< double > &s, Shape &test) const
Function to compute the shape and test functions and to return the Jacobian of mapping between local ...
void output(std::ostream &outfile, const unsigned &n_plot)
Output function – forward to broken version in FiniteElement until somebody decides what exactly they...
double global_power_contribution()
Compute the element's contribution to the time-averaged radiated power over the artificial boundary.
double global_power_contribution(std::ofstream &outfile)
Compute the element's contribution to the time-averaged radiated power over the artificial boundary....
virtual std::complex< unsigned > u_index_helmholtz() const
Return the index at which the real/imag unknown value is stored.
HelmholtzBCElementBase()
Broken empty constructor.
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
Broken assignment operator.
void output(FILE *file_pt)
C-style output function – forward to broken version in FiniteElement until somebody decides what exac...
void output(std::ostream &outfile)
Output function – forward to broken version in FiniteElement until somebody decides what exactly they...
HelmholtzBCElementBase(const HelmholtzBCElementBase &dummy)=delete
Broken copy constructor.
void compute_contribution_to_fourier_components(Vector< std::complex< double > > &a_coeff_pos, Vector< std::complex< double > > &a_coeff_neg)
Compute element's contribution to Fourier components of the solution – length of vector indicates num...
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...
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function – forward to broken version in FiniteElement until somebody decides what exac...
unsigned Dim
The spatial dimension of the problem.
std::complex< unsigned > U_index_helmholtz
The index at which the real and imag part of the unknown is stored at the nodes.
FaceElement used to apply Sommerfeld radiation conditon via Dirichlet to Neumann map.
void fill_in_generic_residual_contribution_helmholtz_DtN_bc(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Compute the element's residual vector Jacobian matrix. Overloaded version, using the gamma computed i...
HelmholtzDtNBoundaryElement(FiniteElement *const &bulk_el_pt, const int &face_index)
Construct element from specification of bulk element and face index.
void compute_gamma_contribution(const double &phi, const int &n, std::complex< double > &gamma_con, std::map< unsigned, std::complex< double > > &d_gamma_con)
Compute the contribution of the element to the Gamma integral and its derivates w....
void set_outer_boundary_mesh_pt(HelmholtzDtNMesh< ELEMENT > *mesh_pt)
Set mesh of all DtN boundary condition elements.
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector.
HelmholtzDtNMesh< ELEMENT > * outer_boundary_mesh_pt() const
Access function to mesh of all DtN boundary condition elements (needed to get access to gamma values)
HelmholtzDtNMesh< ELEMENT > * Outer_boundary_mesh_pt
Pointer to mesh of all DtN boundary condition elements (needed to get access to gamma values)
void complete_setup_of_dependencies()
Complete the setup of additional dependencies arising through the far-away interaction with other nod...
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.
================================================================= Mesh for DtN boundary condition ele...
Vector< std::map< unsigned, std::complex< double > > > & d_gamma_at_gauss_point(FiniteElement *el_pt)
Derivative of Gamma integral w.r.t global unknown, evaluated at Gauss points for specified element.
std::map< FiniteElement *, Vector< std::complex< double > > > Gamma_at_gauss_point
Container to store the gamma integral for given Gauss point and element.
std::map< FiniteElement *, Vector< std::map< unsigned, std::complex< double > > > > D_Gamma_at_gauss_point
Container to store the derivate of Gamma integral w.r.t global unknown evaluated at Gauss points for ...
unsigned Nfourier_terms
Nbr of Fourier terms used in the Gamma computation.
void setup_gamma()
Compute and store the gamma integral at all integration points of the constituent elements.
double & outer_radius()
The outer radius.
void compute_fourier_components(Vector< std::complex< double > > &a_coeff_pos, Vector< std::complex< double > > &a_coeff_neg)
Compute Fourier components of the solution – length of vector indicates number of terms to be compute...
double Outer_radius
Outer radius.
Vector< std::complex< double > > & gamma_at_gauss_point(FiniteElement *el_pt)
Gamma integral evaluated at Gauss points for specified element.
HelmholtzDtNMesh(const double &outer_radius, const unsigned &nfourier_terms)
Constructor: Specify radius of outer boundary and number of Fourier terms used in the computation of ...
unsigned & nfourier_terms()
Number of Fourier terms used in the computation of the gamma integral.
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
virtual double weight(const unsigned &i) const =0
Return weight of i-th integration point.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
An OomphLibError object which should be thrown when an run-time error is encountered....
An OomphLibWarning object which should be created as a temporary object to issue a warning....
RefineableElements are FiniteElements that may be subdivided into children to provide a better local ...
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
TAdvectionDiffusionReactionElement<NREAGENT,DIM,NNODE_1D> elements are isoparametric triangular DIM-d...
TAdvectionDiffusionReactionElement()
Constructor: Call constructors for TElement and AdvectionDiffusionReaction equations.
A slight extension to the standard template vector class so that we can include "graceful" array rang...
void CHankel_first(const unsigned &n, const std::complex< double > &x, Vector< std::complex< double > > &h, Vector< std::complex< double > > &hp)
Compute Hankel function of the first kind of orders 0...n and its derivates at coordinate x....
void Hankel_first(const unsigned &n, const double &x, Vector< std::complex< double > > &h, Vector< std::complex< double > > &hp)
Compute Hankel function of the first kind of orders 0...n and its derivates at coordinate x....
const double Pi
50 digits from maple
double Tol
Relative tolerance to within radius of points on DtN boundary are allowed to deviate from specified v...
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).