28 #ifndef OOMPH_FOURIER_DECOMPOSED_HELMHOLTZ_BC_ELEMENTS_HEADER
29 #define OOMPH_FOURIER_DECOMPOSED_HELMHOLTZ_BC_ELEMENTS_HEADER
34 #include <oomph-lib-config.h>
58 template<
class ELEMENT>
73 "FourierDecomposedHelmholtzBCElementBase",
98 const unsigned&
i)
const
113 void output(std::ostream& outfile,
const unsigned& n_plot)
128 void output(FILE* file_pt,
const unsigned& n_plot)
138 return std::complex<unsigned>(
148 std::ofstream outfile;
159 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(this->
bulk_element_pt());
162 unsigned nnode_bulk = bulk_elem_pt->nnode();
163 const unsigned n_node_local = this->
nnode();
166 const unsigned bulk_dim = bulk_elem_pt->dim();
167 const unsigned local_dim = this->
node_pt(0)->
ndim();
170 Shape psi(n_node_local);
173 Shape psi_bulk(nnode_bulk);
174 DShape dpsi_bulk_dx(nnode_bulk, bulk_dim);
187 if (outfile.is_open())
194 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
197 for (
unsigned i = 0;
i < (local_dim - 1);
i++)
219 (void)bulk_elem_pt->dshape_eulerian(s_bulk, psi_bulk, dpsi_bulk_dx);
223 std::complex<double> dphi_dn(0.0, 0.0);
225 std::complex<double> interpolated_phi(0.0, 0.0);
231 for (
unsigned l = 0; l < nnode_bulk; l++)
234 const std::complex<double> phi_value(
235 bulk_elem_pt->nodal_value(
236 l, bulk_elem_pt->u_index_fourier_decomposed_helmholtz().real()),
237 bulk_elem_pt->nodal_value(
238 l, bulk_elem_pt->u_index_fourier_decomposed_helmholtz().imag()));
241 for (
unsigned i = 0;
i < bulk_dim;
i++)
243 interpolated_dphidx[
i] += phi_value * dpsi_bulk_dx(l,
i);
247 for (
unsigned l = 0; l < n_node_local; l++)
250 const std::complex<double> phi_value(
254 interpolated_phi += phi_value * psi(l);
258 for (
unsigned i = 0;
i < bulk_dim;
i++)
260 dphi_dn += interpolated_dphidx[
i] * unit_normal[
i];
264 double integrand = (interpolated_phi.real() * dphi_dn.imag() -
265 interpolated_phi.imag() * dphi_dn.real());
270 if (outfile.is_open())
272 outfile <<
x[0] <<
" " <<
x[1] <<
" " <<
theta <<
" " << integrand
294 unsigned nnod =
nnode();
295 for (
unsigned i = 0;
i < nnod;
i++)
315 unsigned n_node =
nnode();
321 for (
unsigned i = 0;
i < n_node;
i++)
323 for (
unsigned j = 0;
j < 1;
j++)
326 dtest_ds(
i,
j) = dpsi_ds(
i,
j);
349 template<
class ELEMENT>
408 std::map<FiniteElement*, Vector<std::map<unsigned, std::complex<double>>>>
419 template<
class ELEMENT>
449 residuals, jacobian, 1);
460 std::complex<double>& gamma_con,
461 std::map<
unsigned, std::complex<double>>& d_gamma_con);
485 std::set<Node*> node_set;
487 for (
unsigned e = 0;
e < nel;
e++)
490 unsigned nnod = el_pt->
nnode();
491 for (
unsigned j = 0;
j < nnod;
j++)
498 node_set.insert(nod_pt);
503 unsigned nnod = this->
nnode();
504 for (
unsigned j = 0;
j < nnod;
j++)
507 node_set.erase(nod_pt);
519 for (std::set<Node*>::iterator it = node_set.begin();
520 it != node_set.end();
535 const unsigned& flag)
538 const unsigned n_node = this->
nnode();
551 int local_eqn_real = 0, local_unknown_real = 0, global_unk_real = 0,
552 local_eqn_imag = 0, local_unknown_imag = 0, global_unk_imag = 0;
553 int external_global_unk_real = 0, external_unknown_real = 0,
554 external_global_unk_imag = 0, external_unknown_imag = 0;
567 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
570 for (
unsigned i = 0;
i < 1;
i++)
588 for (
unsigned j = 0;
j < n_node;
j++)
595 for (
unsigned l = 0; l < n_node; l++)
604 if (local_eqn_real >= 0)
607 residuals[local_eqn_real] +=
gamma[ipt].real() *
test[l] *
r *
W;
614 for (
unsigned l2 = 0; l2 < n_node; l2++)
624 if (local_unknown_real >= 0)
627 global_unk_real = this->
eqn_number(local_unknown_real);
628 jacobian(local_eqn_real, local_unknown_real) +=
629 d_gamma[ipt][global_unk_real].real() *
test[l] *
r *
W;
631 if (local_unknown_imag >= 0)
634 global_unk_imag = this->
eqn_number(local_unknown_imag);
635 jacobian(local_eqn_real, local_unknown_imag) +=
636 d_gamma[ipt][global_unk_imag].real() *
test[l] *
r *
W;
643 for (
unsigned l2 = 0; l2 < n_ext_data; l2++)
653 if (external_unknown_real >= 0)
656 external_global_unk_real =
658 jacobian(local_eqn_real, external_unknown_real) +=
659 d_gamma[ipt][external_global_unk_real].real() *
test[l] *
662 if (external_unknown_imag >= 0)
665 external_global_unk_imag =
667 jacobian(local_eqn_real, external_unknown_imag) +=
668 d_gamma[ipt][external_global_unk_imag].real() *
test[l] *
675 if (local_eqn_imag >= 0)
678 residuals[local_eqn_imag] +=
gamma[ipt].imag() *
test[l] *
r *
W;
685 for (
unsigned l2 = 0; l2 < n_node; l2++)
695 if (local_unknown_real >= 0)
698 global_unk_real = this->
eqn_number(local_unknown_real);
699 jacobian(local_eqn_imag, local_unknown_real) +=
700 d_gamma[ipt][global_unk_real].imag() *
test[l] *
r *
W;
702 if (local_unknown_imag >= 0)
705 global_unk_imag = this->
eqn_number(local_unknown_imag);
706 jacobian(local_eqn_imag, local_unknown_imag) +=
707 d_gamma[ipt][global_unk_imag].imag() *
test[l] *
r *
W;
715 for (
unsigned l2 = 0; l2 < n_ext_data; l2++)
725 if (external_unknown_real >= 0)
728 external_global_unk_real =
730 jacobian(local_eqn_imag, external_unknown_real) +=
731 d_gamma[ipt][external_global_unk_real].imag() *
test[l] *
734 if (external_unknown_imag >= 0)
737 external_global_unk_imag =
739 jacobian(local_eqn_imag, external_unknown_imag) +=
740 d_gamma[ipt][external_global_unk_imag].imag() *
test[l] *
770 template<
class ELEMENT>
775 std::complex<double>& gamma_con,
776 std::map<
unsigned, std::complex<double>>& d_gamma_con)
779 int n_fourier_helmholtz =
780 dynamic_cast<ELEMENT*
>(this->bulk_element_pt())->fourier_wavenumber();
783 const std::complex<double>
I(0.0, 1.0);
786 const unsigned n_node = this->nnode();
793 int local_unknown_real = 0, local_unknown_imag = 0;
794 int global_eqn_real = 0, global_eqn_imag = 0;
797 const unsigned n_intpt = this->integral_pt()->nweight();
803 gamma_con = std::complex<double>(0.0, 0.0);
808 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
811 for (
unsigned i = 0;
i < 1;
i++)
813 s[
i] = this->integral_pt()->knot(ipt,
i);
817 double w = this->integral_pt()->weight(ipt);
820 this->dshape_local(
s, psi, dpsi);
827 std::complex<double> interpolated_u(0.0, 0.0);
830 for (
unsigned l = 0; l < n_node; l++)
833 for (
unsigned i = 0;
i < 2;
i++)
835 interpolated_x[
i] += this->nodal_position(l,
i) * psi[l];
836 interpolated_dxds[
i] += this->nodal_position(l,
i) * dpsi(l, 0);
840 std::complex<double> u_value(
842 this->U_index_fourier_decomposed_helmholtz.real()),
844 this->U_index_fourier_decomposed_helmholtz.imag()));
846 interpolated_u += u_value * psi(l);
854 double phi =
atan2(interpolated_x[0], interpolated_x[1]);
857 double dphi_ds = -
std::fabs(-interpolated_dxds[1] / interpolated_x[0]);
866 gamma_con += interpolated_u * p_phi * p_theta *
sin(phi) *
w * dphi_ds;
869 for (
unsigned l = 0; l < n_node; l++)
872 local_unknown_real = this->nodal_local_eqn(
873 l, this->U_index_fourier_decomposed_helmholtz.real());
874 if (local_unknown_real >= 0)
876 global_eqn_real = this->eqn_number(local_unknown_real);
877 d_gamma_con[global_eqn_real] +=
878 psi(l) * p_phi * p_theta *
sin(phi) *
w * dphi_ds;
882 local_unknown_imag = this->nodal_local_eqn(
883 l, this->U_index_fourier_decomposed_helmholtz.imag());
884 if (local_unknown_imag >= 0)
886 global_eqn_imag = this->eqn_number(local_unknown_imag);
887 d_gamma_con[global_eqn_imag] +=
888 I * psi(l) * p_phi * p_theta *
sin(phi) *
w * dphi_ds;
904 namespace ToleranceForFourierDecomposedHelmholtzOuterBoundary
917 namespace ToleranceForFourierDecomposedHelmholtzOuterBoundary
935 template<
class ELEMENT>
941 unsigned nel = this->nelement();
942 for (
unsigned e = 0;
e < nel;
e++)
945 unsigned nnod = fe_pt->
nnode();
946 for (
unsigned j = 0;
j < nnod;
j++)
956 double r =
sqrt(
x[0] *
x[0] +
x[1] *
x[1]);
961 throw OomphLibError(
"Outer radius for DtN BC must not be zero!",
969 std::ostringstream error_stream;
971 <<
"Node at " <<
x[0] <<
" " <<
x[1] <<
" has radius " <<
r
972 <<
" which does not "
973 <<
" agree with \nspecified outer radius " << this->
Outer_radius
974 <<
" within relative tolerance "
976 <<
".\nYou can adjust the tolerance via\n"
977 <<
"ToleranceForFourierDecomposedHelmholtzOuterBoundary::Tol\n"
978 <<
"or recompile without PARANOID.\n";
992 this->element_pt(0));
995 int n_fourier_decomposed =
996 dynamic_cast<ELEMENT*
>(el_pt->
bulk_element_pt())->fourier_wavenumber();
998 double n_hankel_order_tmp = 0.0;
1001 std::complex<double>
I(0.0, 1.0);
1005 q(
N_terms + 1, std::complex<double>(0.0, 0.0));
1021 h_a[
j] = jv[
j] +
I * yv[
j];
1022 hp_a[
j] = djv[
j] +
I * dyv[
j];
1026 for (
unsigned i = n_fourier_decomposed;
i <
N_terms;
i++)
1042 unsigned nel = this->nelement();
1043 for (
unsigned e = 0;
e < nel;
e++)
1048 this->element_pt(
e));
1055 std::complex<double>(0.0, 0.0));
1059 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
1066 for (
unsigned i = 0;
i < el_pt->
dim();
i++)
1078 std::complex<double> gamma_con(0.0, 0.0);
1079 std::map<unsigned, std::complex<double>> d_gamma_con;
1082 for (
unsigned nn = n_fourier_decomposed; nn <
N_terms; nn++)
1086 for (
unsigned ee = 0; ee < nel; ee++)
1091 this->element_pt(ee));
1095 theta, nn, gamma_con, d_gamma_con);
1097 unsigned n_node = eel_pt->
nnode();
1099 gamma_vector[ipt] +=
q[nn] * gamma_con;
1100 for (
unsigned l = 0; l < n_node; l++)
1106 if (local_unknown_real >= 0)
1108 int global_eqn_real = eel_pt->
eqn_number(local_unknown_real);
1109 d_gamma_vector[ipt][global_eqn_real] +=
1110 q[nn] * d_gamma_con[global_eqn_real];
1117 if (local_unknown_imag >= 0)
1119 int global_eqn_imag = eel_pt->
eqn_number(local_unknown_imag);
1120 d_gamma_vector[ipt][global_eqn_imag] +=
1121 q[nn] * d_gamma_con[global_eqn_imag];
1129 Gamma_at_gauss_point[el_pt] = gamma_vector;
1130 D_Gamma_at_gauss_point[el_pt] = d_gamma_vector;
1138 template<
class ELEMENT>
1141 const int& face_index)
1162 "Bulk element must inherit from FourierDecomposedHelmholtzEquations.";
AnnoyingScalar cos(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:136
AnnoyingScalar atan2(const AnnoyingScalar &y, const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:139
AnnoyingScalar sin(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:137
AnnoyingScalar imag(const AnnoyingScalar &)
Definition: AnnoyingScalar.h:132
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
JacobiRotation< float > J
Definition: Jacobi_makeJacobi.cpp:3
RowVector3d w
Definition: Matrix_resize_int.cpp:3
virtual bool is_a_copy() const
Definition: nodes.h:253
Definition: elements.h:4338
int & face_index()
Definition: elements.h:4626
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:6006
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
Definition: elements.h:4497
Vector< double > local_coordinate_in_bulk(const Vector< double > &s) const
Definition: elements.cc:6353
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
Definition: elements.h:4735
double interpolated_x(const Vector< double > &s, const unsigned &i) const
Definition: elements.h:4528
double J_eulerian(const Vector< double > &s) const
Definition: elements.cc:5242
Definition: elements.h:4998
Definition: elements.h:1313
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
double nodal_value(const unsigned &n, const unsigned &i) const
Definition: elements.h:2593
virtual void output(std::ostream &outfile)
Definition: elements.h:3050
virtual void build_face_element(const int &face_index, FaceElement *face_element_pt)
Definition: elements.cc:5132
virtual void shape(const Vector< double > &s, Shape &psi) const =0
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Definition: elements.h:1432
unsigned dim() const
Definition: elements.h:2611
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
Definition: elements.h:1963
virtual void dshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Definition: elements.h:1981
Definition: fourier_decomposed_helmholtz_bc_elements.h:62
FourierDecomposedHelmholtzBCElementBase()
Broken empty constructor.
Definition: fourier_decomposed_helmholtz_bc_elements.h:70
void output(FILE *file_pt)
Definition: fourier_decomposed_helmholtz_bc_elements.h:120
void output(std::ostream &outfile)
Definition: fourier_decomposed_helmholtz_bc_elements.h:106
double d_shape_and_test_local(const Vector< double > &s, Shape &psi, Shape &test, DShape &dpsi_ds, DShape &dtest_ds) const
Definition: fourier_decomposed_helmholtz_bc_elements.h:308
double global_power_contribution(std::ofstream &outfile)
Definition: fourier_decomposed_helmholtz_bc_elements.h:156
void output(std::ostream &outfile, const unsigned &n_plot)
Definition: fourier_decomposed_helmholtz_bc_elements.h:113
void output(FILE *file_pt, const unsigned &n_plot)
Definition: fourier_decomposed_helmholtz_bc_elements.h:128
double shape_and_test(const Vector< double > &s, Shape &psi, Shape &test) const
Definition: fourier_decomposed_helmholtz_bc_elements.h:287
FourierDecomposedHelmholtzBCElementBase(const FourierDecomposedHelmholtzBCElementBase &dummy)=delete
Broken copy constructor.
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
Broken assignment operator.
Definition: fourier_decomposed_helmholtz_bc_elements.h:96
std::complex< unsigned > U_index_fourier_decomposed_helmholtz
Definition: fourier_decomposed_helmholtz_bc_elements.h:335
double global_power_contribution()
Definition: fourier_decomposed_helmholtz_bc_elements.h:145
virtual std::complex< unsigned > u_index_fourier_decomposed_helmholtz() const
Definition: fourier_decomposed_helmholtz_bc_elements.h:135
Definition: fourier_decomposed_helmholtz_bc_elements.h:422
void fill_in_generic_residual_contribution_fourier_decomposed_helmholtz_DtN_bc(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Definition: fourier_decomposed_helmholtz_bc_elements.h:532
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: fourier_decomposed_helmholtz_bc_elements.h:444
FourierDecomposedHelmholtzDtNBoundaryElement(FiniteElement *const &bulk_el_pt, const int &face_index)
Definition: fourier_decomposed_helmholtz_bc_elements.h:426
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector.
Definition: fourier_decomposed_helmholtz_bc_elements.h:433
void complete_setup_of_dependencies()
Definition: fourier_decomposed_helmholtz_bc_elements.h:482
void compute_gamma_contribution(const double &theta, const unsigned &n, std::complex< double > &gamma_con, std::map< unsigned, std::complex< double >> &d_gamma_con)
Definition: fourier_decomposed_helmholtz_bc_elements.h:772
FourierDecomposedHelmholtzDtNMesh< ELEMENT > * Outer_boundary_mesh_pt
Definition: fourier_decomposed_helmholtz_bc_elements.h:753
void set_outer_boundary_mesh_pt(FourierDecomposedHelmholtzDtNMesh< ELEMENT > *mesh_pt)
Set mesh of all DtN boundary condition elements.
Definition: fourier_decomposed_helmholtz_bc_elements.h:472
FourierDecomposedHelmholtzDtNMesh< ELEMENT > * outer_boundary_mesh_pt() const
Definition: fourier_decomposed_helmholtz_bc_elements.h:466
Definition: fourier_decomposed_helmholtz_bc_elements.h:351
Vector< std::complex< double > > & gamma_at_gauss_point(FiniteElement *el_pt)
Definition: fourier_decomposed_helmholtz_bc_elements.h:367
std::map< FiniteElement *, Vector< std::complex< double > > > Gamma_at_gauss_point
Definition: fourier_decomposed_helmholtz_bc_elements.h:403
Vector< std::map< unsigned, std::complex< double > > > & d_gamma_at_gauss_point(FiniteElement *el_pt)
Definition: fourier_decomposed_helmholtz_bc_elements.h:374
FourierDecomposedHelmholtzDtNMesh(const double &outer_radius, const unsigned &n_terms)
Definition: fourier_decomposed_helmholtz_bc_elements.h:355
double & outer_radius()
The outer radius.
Definition: fourier_decomposed_helmholtz_bc_elements.h:381
void setup_gamma()
of the mesh's constituent elements
Definition: fourier_decomposed_helmholtz_bc_elements.h:936
unsigned N_terms
Number of terms used in the Gamma computation.
Definition: fourier_decomposed_helmholtz_bc_elements.h:398
std::map< FiniteElement *, Vector< std::map< unsigned, std::complex< double > > > > D_Gamma_at_gauss_point
Definition: fourier_decomposed_helmholtz_bc_elements.h:409
double Outer_radius
Outer radius.
Definition: fourier_decomposed_helmholtz_bc_elements.h:395
unsigned & n_terms()
Definition: fourier_decomposed_helmholtz_bc_elements.h:388
Definition: fourier_decomposed_helmholtz_elements.h:84
virtual std::complex< unsigned > u_index_fourier_decomposed_helmholtz() const
Broken assignment operator.
Definition: fourier_decomposed_helmholtz_elements.h:114
unsigned nexternal_data() const
Return the number of external data objects.
Definition: elements.h:829
unsigned long eqn_number(const unsigned &ieqn_local) const
Definition: elements.h:704
unsigned add_external_data(Data *const &data_pt, const bool &fd=true)
Definition: elements.cc:307
static DenseMatrix< double > Dummy_matrix
Definition: elements.h:227
int external_local_eqn(const unsigned &i, const unsigned &j)
Definition: elements.h:311
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.
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:1060
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Definition: nodes.h:1054
virtual Node * copied_node_pt() const
Definition: nodes.h:1107
Definition: oomph_definitions.h:222
float real
Definition: datatypes.h:10
RealScalar s
Definition: level1_cplx_impl.h:130
char char char int int * k
Definition: level2_impl.h:374
#define I
Definition: main.h:127
double theta
Definition: two_d_biharmonic.cc:236
int bessjyv(double v, double x, double &vm, double *jv, double *yv, double *djv, double *dyv)
Definition: crbond_bessel.cc:1050
EIGEN_DEVICE_FUNC const Scalar & q
Definition: SpecialFunctionsImpl.h:2019
squared absolute sa ArrayBase::abs2 DOXCOMMA MatrixBase::cwiseAbs2 sa Eigen::abs2 DOXCOMMA Eigen::pow DOXCOMMA ArrayBase::square nearest sa Eigen::floor DOXCOMMA Eigen::ceil DOXCOMMA ArrayBase::round nearest integer not less than the given sa Eigen::floor DOXCOMMA ArrayBase::ceil not a number test
Definition: GlobalFunctions.h:109
double Outer_radius
Radius of outer boundary (must be a circle!)
Definition: helmholtz_point_source.cc:71
unsigned N_terms
Number of terms in series.
Definition: sphere_scattering.cc:112
Real fabs(const Real &a)
Definition: boostmultiprec.cpp:117
Mdouble gamma(Mdouble gamma_in)
This is the gamma function returns the true value for the half integer value.
Definition: ExtendedMath.cc:116
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
double factorial(const unsigned &l)
Factorial.
Definition: fourier_decomposed_helmholtz_elements.cc:40
double plgndr2(const unsigned &l, const unsigned &m, const double &x)
Legendre polynomials depending on two parameters.
Definition: fourier_decomposed_helmholtz_elements.cc:97
const double Pi
50 digits from maple
Definition: oomph_utilities.h:157
@ W
Definition: quadtree.h:63
double Tol
Definition: fourier_decomposed_helmholtz_bc_elements.h:921
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
list x
Definition: plotDoE.py:28
Definition: indexed_view.cpp:20
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2