28 #ifndef OOMPH_HELMHOLTZ_BC_ELEMENTS_HEADER
29 #define OOMPH_HELMHOLTZ_BC_ELEMENTS_HEADER
33 #include <oomph-lib-config.h>
55 namespace Hankel_functions_for_helmholtz_problem
64 Vector<std::complex<double>>& h,
65 Vector<std::complex<double>>& hp)
70 int(
n),
x, n_actual, &jn[0], &yn[0], &jnp[0], &ynp[0]);
72 if (n_actual !=
int(
n))
74 std::ostringstream error_stream;
75 error_stream <<
"CRBond_Bessel::bessjyna() only computed " << n_actual
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]);
84 hp[
i] = std::complex<double>(jnp[
i], ynp[
i]);
96 const std::complex<double>&
x,
97 Vector<std::complex<double>>& h,
98 Vector<std::complex<double>>& hp)
117 int(
n),
x, n_actual, &jn[0], &yn[0], &jnp[0], &ynp[0]);
121 if (n_actual !=
int(
n))
124 std::ostringstream error_message_stream;
127 error_message_stream <<
"CRBond_Bessel::cbessjyna() only computed "
128 << n_actual <<
" rather than " <<
n
129 <<
" Bessel functions.\n";
140 for (
unsigned i = 0;
i <
n;
i++)
143 h[
i] = std::complex<double>(jn[
i].
real() - yn[
i].
imag(),
147 hp[
i] = std::complex<double>(jnp[
i].
real() - ynp[
i].
imag(),
165 template<
class ELEMENT>
179 "Don't call empty constructor for HelmholtzBCElementBase",
203 const unsigned&
i)
const
218 void output(std::ostream& outfile,
const unsigned& n_plot)
233 void output(FILE* file_pt,
const unsigned& n_plot)
251 std::ofstream outfile;
262 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(this->
bulk_element_pt());
265 unsigned nnode_bulk = bulk_elem_pt->nnode();
266 const unsigned n_node_local =
nnode();
269 const unsigned bulk_dim = bulk_elem_pt->dim();
270 const unsigned local_dim = this->
dim();
273 Shape psi(n_node_local);
276 Shape psi_bulk(nnode_bulk);
277 DShape dpsi_bulk_dx(nnode_bulk, bulk_dim);
290 if (outfile.is_open())
297 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
300 for (
unsigned i = 0;
i < local_dim;
i++)
322 (void)bulk_elem_pt->dshape_eulerian(s_bulk, psi_bulk, dpsi_bulk_dx);
326 std::complex<double> dphi_dn(0.0, 0.0);
328 std::complex<double> interpolated_phi(0.0, 0.0);
334 for (
unsigned l = 0; l < nnode_bulk; l++)
337 const std::complex<double> phi_value(
338 bulk_elem_pt->nodal_value(l,
339 bulk_elem_pt->u_index_helmholtz().real()),
340 bulk_elem_pt->nodal_value(
341 l, bulk_elem_pt->u_index_helmholtz().imag()));
344 for (
unsigned i = 0;
i < bulk_dim;
i++)
346 interpolated_dphidx[
i] += phi_value * dpsi_bulk_dx(l,
i);
350 for (
unsigned l = 0; l < n_node_local; l++)
353 const std::complex<double> phi_value(
357 interpolated_phi += phi_value * psi(l);
361 for (
unsigned i = 0;
i < bulk_dim;
i++)
363 dphi_dn += interpolated_dphidx[
i] * unit_normal[
i];
367 double integrand = 0.5 * (interpolated_phi.real() * dphi_dn.imag() -
368 interpolated_phi.imag() * dphi_dn.real());
371 if (outfile.is_open())
374 double phi =
atan2(
x[1],
x[0]);
375 outfile <<
x[0] <<
" " <<
x[1] <<
" " << phi <<
" " << integrand
380 power += integrand *
W;
390 Vector<std::complex<double>>& a_coeff_pos,
391 Vector<std::complex<double>>& a_coeff_neg)
394 if (a_coeff_pos.size() != a_coeff_neg.size())
396 std::ostringstream error_stream;
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);
408 const unsigned n_node = this->
nnode();
421 unsigned n = a_coeff_pos.size();
422 for (
unsigned i = 0;
i <
n;
i++)
424 a_coeff_pos[
i] = std::complex<double>(0.0, 0.0);
425 a_coeff_neg[
i] = std::complex<double>(0.0, 0.0);
430 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
433 for (
unsigned i = 0;
i < (this->
Dim - 1);
i++)
449 std::complex<double> interpolated_u(0.0, 0.0);
452 for (
unsigned l = 0; l < n_node; l++)
455 for (
unsigned i = 0;
i < this->
Dim;
i++)
462 const std::complex<double> u_value(
464 this->nodal_value(l, this->U_index_helmholtz.imag()));
467 interpolated_u += u_value * psi(l);
484 for (
unsigned i = 0;
i <
n;
i++)
487 interpolated_u *
exp(-
I * phi *
double(
i)) * dphi_ds *
w;
490 for (
unsigned i = 1;
i <
n;
i++)
493 interpolated_u *
exp(
I * phi *
double(
i)) * dphi_ds *
w;
524 unsigned n_node =
nnode();
530 for (
unsigned i = 0;
i < n_node;
i++)
532 for (
unsigned j = 0;
j < (
Dim - 1);
j++)
535 dtest_ds(
i,
j) = dpsi_ds(
i,
j);
560 template<
class ELEMENT>
578 Vector<std::complex<double>>& a_coeff_neg);
623 std::map<FiniteElement*, Vector<std::map<unsigned, std::complex<double>>>>
637 template<
class ELEMENT>
677 residuals, jacobian, 1);
694 const unsigned& flag)
707 throw OomphLibError(
"Pointer to outer radius hasn't been set!",
715 const unsigned n_node = this->
nnode();
719 DShape dpsi_ds(n_node, this->
Dim - 1), dtest_ds(n_node, this->
Dim - 1),
720 dtest_dS(n_node, this->
Dim - 1), dpsi_dS(n_node, this->
Dim - 1);
729 int local_eqn_real = 0, local_unknown_real = 0;
730 int local_eqn_imag = 0, local_unknown_imag = 0;
739 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
742 for (
unsigned i = 0;
i < (this->
Dim - 1);
i++)
759 double inv_J = 1 /
J;
763 std::complex<double> interpolated_u(0.0, 0.0);
764 std::complex<double> du_dS(0.0, 0.0);
767 for (
unsigned l = 0; l < n_node; l++)
771 const std::complex<double> u_value(
773 this->nodal_value(l, this->U_index_helmholtz.imag()));
775 interpolated_u += u_value * psi[l];
777 du_dS += u_value * dpsi_ds(l, 0) * inv_J;
780 dtest_dS(l, 0) = dtest_ds(l, 0) * inv_J;
782 dpsi_dS(l, 0) = dpsi_ds(l, 0) * inv_J;
790 for (
unsigned l = 0; l < n_node; l++)
800 if (local_eqn_real >= 0)
804 residuals[local_eqn_real] += (
k * interpolated_u.imag() +
805 (0.5 /
R) * interpolated_u.real()) *
813 for (
unsigned l2 = 0; l2 < n_node; l2++)
820 if (local_unknown_real >= 0)
822 jacobian(local_eqn_real, local_unknown_real) +=
823 (0.5 /
R) * psi[l2] *
test[l] *
W;
827 if (local_unknown_imag >= 0)
829 jacobian(local_eqn_real, local_unknown_imag) +=
830 k * psi[l2] *
test[l] *
W;
839 if (local_eqn_imag >= 0)
842 residuals[local_eqn_imag] += (-
k * interpolated_u.real() +
843 (0.5 /
R) * interpolated_u.imag()) *
852 for (
unsigned l2 = 0; l2 < n_node; l2++)
859 if (local_unknown_real >= 0)
861 jacobian(local_eqn_imag, local_unknown_real) +=
862 (-
k) * psi[l2] *
test[l] *
W;
866 if (local_unknown_imag >= 0)
868 jacobian(local_eqn_imag, local_unknown_imag) +=
869 (0.5 /
R) * psi[l2] *
test[l] *
W;
882 for (
unsigned l = 0; l < n_node; l++)
892 if (local_eqn_real >= 0)
896 residuals[local_eqn_real] +=
897 (
k * interpolated_u.imag() +
898 (0.5 /
R) * interpolated_u.real()) *
900 ((0.125 / (
k *
R *
R)) * interpolated_u.imag()) *
test[l] *
W;
902 residuals[local_eqn_real] +=
903 (-0.5 /
k) * du_dS.imag() * dtest_dS(l, 0) *
W;
910 for (
unsigned l2 = 0; l2 < n_node; l2++)
917 if (local_unknown_real >= 0)
919 jacobian(local_eqn_real, local_unknown_real) +=
920 (0.5 /
R) * psi[l2] *
test[l] *
W;
924 if (local_unknown_imag >= 0)
926 jacobian(local_eqn_real, local_unknown_imag) +=
927 k * psi[l2] *
test[l] *
W +
928 (0.125 / (
k *
R *
R)) * psi[l2] *
test[l] *
W;
930 jacobian(local_eqn_real, local_unknown_imag) +=
931 (-0.5 /
k) * dpsi_dS(l2, 0) * dtest_dS(l, 0) *
W;
940 if (local_eqn_imag >= 0)
943 residuals[local_eqn_imag] +=
944 (-
k * interpolated_u.real() +
945 (0.5 /
R) * interpolated_u.imag()) *
947 ((-0.125 / (
k *
R *
R)) * interpolated_u.real()) *
test[l] *
W;
949 residuals[local_eqn_imag] +=
950 (0.5 /
k) * du_dS.real() * dtest_dS(l, 0) *
W;
957 for (
unsigned l2 = 0; l2 < n_node; l2++)
964 if (local_unknown_real >= 0)
966 jacobian(local_eqn_imag, local_unknown_real) +=
967 (-
k) * psi[l2] *
test[l] *
W -
968 (0.125 / (
k *
R *
R)) * psi[l2] *
test[l] *
W;
970 jacobian(local_eqn_imag, local_unknown_real) +=
971 (0.5 /
k) * dpsi_dS(l2, 0) * dtest_dS(l, 0) *
W;
975 if (local_unknown_imag >= 0)
977 jacobian(local_eqn_imag, local_unknown_imag) +=
978 (0.5 /
R) * psi[l2] *
test[l] *
W;
990 for (
unsigned l = 0; l < n_node; l++)
1000 if (local_eqn_real >= 0)
1003 residuals[local_eqn_real] +=
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()) *
1009 residuals[local_eqn_real] +=
1010 ((-0.5 /
k) * du_dS.imag() +
1011 (0.5 / (
k *
k *
R)) * du_dS.real()) *
1019 for (
unsigned l2 = 0; l2 < n_node; l2++)
1021 local_unknown_real =
1023 local_unknown_imag =
1026 if (local_unknown_real >= 0)
1028 jacobian(local_eqn_real, local_unknown_real) +=
1029 (0.5 /
R - 0.125 / (
k *
k *
R *
R *
R)) * psi[l2] *
1032 jacobian(local_eqn_real, local_unknown_real) +=
1033 (0.5 / (
k *
k *
R)) * dpsi_dS(l2, 0) * dtest_dS(l, 0) *
W;
1037 if (local_unknown_imag >= 0)
1039 jacobian(local_eqn_real, local_unknown_imag) +=
1040 (
k * (1 + 0.125 / (
k *
k *
R *
R))) * psi[l2] *
test[l] *
1043 jacobian(local_eqn_real, local_unknown_imag) +=
1044 (-0.5 /
k) * dpsi_dS(l2, 0) * dtest_dS(l, 0) *
W;
1053 if (local_eqn_imag >= 0)
1056 residuals[local_eqn_imag] +=
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()) *
1062 residuals[local_eqn_imag] +=
1063 ((0.5 /
k) * du_dS.real() +
1064 (0.5 / (
k *
k *
R)) * du_dS.imag()) *
1072 for (
unsigned l2 = 0; l2 < n_node; l2++)
1074 local_unknown_real =
1076 local_unknown_imag =
1079 if (local_unknown_real >= 0)
1081 jacobian(local_eqn_imag, local_unknown_real) +=
1082 (-
k * (1 + 0.125 / (
k *
k *
R *
R))) * psi[l2] *
test[l] *
1085 jacobian(local_eqn_imag, local_unknown_real) +=
1086 (0.5 /
k) * dpsi_dS(l2, 0) * dtest_dS(l, 0) *
W;
1089 if (local_unknown_imag >= 0)
1091 jacobian(local_eqn_imag, local_unknown_imag) +=
1092 (0.5 /
R - 0.125 / (
k *
k *
R *
R *
R)) * psi[l2] *
1095 jacobian(local_eqn_imag, local_unknown_imag) +=
1096 (0.5 / (
k *
k *
R)) * dpsi_dS(l2, 0) * dtest_dS(l, 0) *
W;
1119 template<
class ELEMENT>
1147 residuals, jacobian, 1);
1157 std::complex<double>& gamma_con,
1158 std::map<
unsigned, std::complex<double>>& d_gamma_con);
1181 std::set<Node*> node_set;
1183 for (
unsigned e = 0;
e < nel;
e++)
1186 unsigned nnod = el_pt->
nnode();
1187 for (
unsigned j = 0;
j < nnod;
j++)
1194 node_set.insert(nod_pt);
1199 unsigned nnod = this->
nnode();
1200 for (
unsigned j = 0;
j < nnod;
j++)
1203 node_set.erase(nod_pt);
1215 for (std::set<Node*>::iterator it = node_set.begin();
1216 it != node_set.end();
1231 const unsigned& flag)
1234 const unsigned n_node = this->
nnode();
1246 int local_eqn_real = 0, local_unknown_real = 0, global_eqn_real = 0,
1247 local_eqn_imag = 0, local_unknown_imag = 0, global_eqn_imag = 0;
1248 int external_global_eqn_real = 0, external_unknown_real = 0,
1249 external_global_eqn_imag = 0, external_unknown_imag = 0;
1262 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
1265 for (
unsigned i = 0;
i < (this->
Dim - 1);
i++)
1283 for (
unsigned l = 0; l < n_node; l++)
1291 if (local_eqn_real >= 0)
1294 residuals[local_eqn_real] -=
gamma[ipt].real() *
test[l] *
W;
1301 for (
unsigned l2 = 0; l2 < n_node; l2++)
1304 local_unknown_real =
1307 local_unknown_imag =
1311 if (local_unknown_real >= 0)
1313 global_eqn_real = this->
eqn_number(local_unknown_real);
1316 jacobian(local_eqn_real, local_unknown_real) -=
1317 d_gamma[ipt][global_eqn_real].real() *
test[l] *
W;
1319 if (local_unknown_imag >= 0)
1321 global_eqn_imag = this->
eqn_number(local_unknown_imag);
1324 jacobian(local_eqn_real, local_unknown_imag) -=
1325 d_gamma[ipt][global_eqn_imag].real() *
test[l] *
W;
1332 for (
unsigned l2 = 0; l2 < n_ext_data; l2++)
1335 external_unknown_real =
1338 external_unknown_imag =
1342 if (external_unknown_real >= 0)
1344 external_global_eqn_real =
1348 jacobian(local_eqn_real, external_unknown_real) -=
1349 d_gamma[ipt][external_global_eqn_real].real() *
test[l] *
W;
1351 if (external_unknown_imag >= 0)
1353 external_global_eqn_imag =
1357 jacobian(local_eqn_real, external_unknown_imag) -=
1358 d_gamma[ipt][external_global_eqn_imag].real() *
test[l] *
W;
1364 if (local_eqn_imag >= 0)
1367 residuals[local_eqn_imag] -=
gamma[ipt].imag() *
test[l] *
W;
1374 for (
unsigned l2 = 0; l2 < n_node; l2++)
1377 local_unknown_real =
1380 local_unknown_imag =
1384 if (local_unknown_real >= 0)
1386 global_eqn_real = this->
eqn_number(local_unknown_real);
1389 jacobian(local_eqn_imag, local_unknown_real) -=
1390 d_gamma[ipt][global_eqn_real].imag() *
test[l] *
W;
1392 if (local_unknown_imag >= 0)
1394 global_eqn_imag = this->
eqn_number(local_unknown_imag);
1397 jacobian(local_eqn_imag, local_unknown_imag) -=
1398 d_gamma[ipt][global_eqn_imag].imag() *
test[l] *
W;
1405 for (
unsigned l2 = 0; l2 < n_ext_data; l2++)
1408 external_unknown_real =
1411 external_unknown_imag =
1415 if (external_unknown_real >= 0)
1417 external_global_eqn_real =
1421 jacobian(local_eqn_imag, external_unknown_real) -=
1422 d_gamma[ipt][external_global_eqn_real].imag() *
test[l] *
W;
1424 if (external_unknown_imag >= 0)
1426 external_global_eqn_imag =
1430 jacobian(local_eqn_imag, external_unknown_imag) -=
1431 d_gamma[ipt][external_global_eqn_imag].imag() *
test[l] *
W;
1458 template<
class ELEMENT>
1462 std::complex<double>& gamma_con,
1463 std::map<
unsigned, std::complex<double>>& d_gamma_con)
1466 const std::complex<double>
I(0.0, 1.0);
1469 const unsigned n_node = this->nnode();
1476 int local_unknown_real = 0, local_unknown_imag = 0;
1477 int global_unknown_real = 0, global_unknown_imag = 0;
1480 const unsigned n_intpt = this->integral_pt()->nweight();
1486 gamma_con = std::complex<double>(0.0, 0.0);
1487 d_gamma_con.clear();
1491 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
1494 for (
unsigned i = 0;
i < (this->
Dim - 1);
i++)
1496 s[
i] = this->integral_pt()->knot(ipt,
i);
1500 double w = this->integral_pt()->weight(ipt);
1503 this->dshape_local(
s, psi, dpsi);
1510 std::complex<double> interpolated_u(0.0, 0.0);
1513 for (
unsigned l = 0; l < n_node; l++)
1516 for (
unsigned i = 0;
i < this->
Dim;
i++)
1518 interpolated_x[
i] += this->nodal_position(l,
i) * psi[l];
1519 interpolated_dxds[
i] += this->nodal_position(l,
i) * dpsi(l, 0);
1523 std::complex<double> u_value(
1524 this->nodal_value(l, this->U_index_helmholtz.real()),
1525 this->nodal_value(l, this->U_index_helmholtz.imag()));
1527 interpolated_u += u_value * psi(l);
1533 double phi_p =
atan2(interpolated_x[1], interpolated_x[0]);
1536 double denom = (interpolated_x[0] * interpolated_x[0]) +
1537 (interpolated_x[1] * interpolated_x[1]);
1538 double nom = -interpolated_dxds[1] * interpolated_x[0] +
1539 interpolated_dxds[0] * interpolated_x[1];
1540 double dphi_ds =
std::fabs(nom / denom);
1546 gamma_con += (dphi_ds)*
w *
1547 pow(
exp(
I * (phi - phi_p)),
static_cast<double>(
n)) *
1551 for (
unsigned l = 0; l < n_node; l++)
1554 local_unknown_real =
1555 this->nodal_local_eqn(l, this->U_index_helmholtz.real());
1556 if (local_unknown_real >= 0)
1558 global_unknown_real = this->eqn_number(local_unknown_real);
1559 d_gamma_con[global_unknown_real] +=
1560 (dphi_ds)*
w *
exp(
I * (phi - phi_p) *
double(
n)) * psi(l);
1564 local_unknown_imag =
1565 this->nodal_local_eqn(l, this->U_index_helmholtz.imag());
1566 if (local_unknown_imag >= 0)
1568 global_unknown_imag = this->eqn_number(local_unknown_imag);
1572 d_gamma_con[global_unknown_imag] +=
1574 pow(
exp(
I * (phi - phi_p)),
static_cast<double>(
n)) * psi(l);
1590 namespace ToleranceForHelmholtzOuterBoundary
1603 namespace ToleranceForHelmholtzOuterBoundary
1620 template<
class ELEMENT>
1622 Vector<std::complex<double>>& a_coeff_pos,
1623 Vector<std::complex<double>>& a_coeff_neg)
1626 if (a_coeff_pos.size() != a_coeff_neg.size())
1628 std::ostringstream error_stream;
1629 error_stream <<
"a_coeff_pos and a_coeff_neg must have "
1630 <<
"the same size. \n";
1637 unsigned n = a_coeff_pos.size();
1640 for (
unsigned i = 0;
i <
n;
i++)
1642 a_coeff_pos[
i] = std::complex<double>(0.0, 0.0);
1643 a_coeff_neg[
i] = std::complex<double>(0.0, 0.0);
1647 unsigned nel = this->nelement();
1648 for (
unsigned e = 0;
e < nel;
e++)
1659 for (
unsigned i = 0;
i <
n;
i++)
1661 a_coeff_pos[
i] += el_a_coeff_pos[
i];
1662 a_coeff_neg[
i] += el_a_coeff_neg[
i];
1673 template<
class ELEMENT>
1679 unsigned nel = this->nelement();
1680 for (
unsigned e = 0;
e < nel;
e++)
1683 unsigned nnod = fe_pt->
nnode();
1684 for (
unsigned j = 0;
j < nnod;
j++)
1690 x[0] = nod_pt->
x(0);
1691 x[1] = nod_pt->
x(1);
1694 double r =
sqrt(
x[0] *
x[0] +
x[1] *
x[1]);
1699 throw OomphLibError(
"Outer radius for DtN BC must not be zero!",
1707 std::ostringstream error_stream;
1708 error_stream <<
"Node at " <<
x[0] <<
" " <<
x[1] <<
" has radius "
1709 <<
r <<
" which does not "
1710 <<
" agree with \nspecified outer radius "
1713 <<
".\nYou can adjust the tolerance via\n"
1714 <<
"ToleranceForHelmholtzOuterBoundary::Tol\n"
1715 <<
"or recompile without PARANOID.\n";
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));
1760 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
1763 unsigned ndim_local = el_pt->
dim();
1768 for (
unsigned i = 0;
i < ndim_local;
i++)
1777 double phi =
atan2(
x[1],
x[0]);
1780 std::complex<double> gamma_con_p(0.0, 0.0), gamma_con_n(0.0, 0.0);
1781 std::map<unsigned, std::complex<double>> d_gamma_con_p, d_gamma_con_n;
1784 for (
unsigned nn = 0; nn < Nfourier_terms; nn++)
1788 for (
unsigned ee = 0; ee < nel; ee++)
1792 this->element_pt(ee));
1796 phi,
int(nn), gamma_con_p, d_gamma_con_p);
1800 phi, -
int(nn), gamma_con_n, d_gamma_con_n);
1802 unsigned n_node = eel_pt->
nnode();
1805 gamma_vector[ipt] +=
q[nn] * gamma_con_p;
1806 for (
unsigned l = 0; l < n_node; l++)
1811 if (local_unknown_p_real >= 0)
1813 int global_unknown_p_real =
1815 d_gamma_vector[ipt][global_unknown_p_real] +=
1816 q[nn] * d_gamma_con_p[global_unknown_p_real];
1823 if (local_unknown_p_imag >= 0)
1825 int global_unknown_p_imag =
1828 d_gamma_vector[ipt][global_unknown_p_imag] +=
1829 q[nn] * d_gamma_con_p[global_unknown_p_imag];
1835 gamma_vector[ipt] +=
q[nn] * (gamma_con_p + gamma_con_n);
1836 for (
unsigned l = 0; l < n_node; l++)
1841 if (local_unknown_real >= 0)
1843 int global_unknown_real =
1845 d_gamma_vector[ipt][global_unknown_real] +=
1846 q[nn] * (d_gamma_con_p[global_unknown_real] +
1847 d_gamma_con_n[global_unknown_real]);
1852 if (local_unknown_imag >= 0)
1854 int global_unknown_imag =
1856 d_gamma_vector[ipt][global_unknown_imag] +=
1857 q[nn] * (d_gamma_con_p[global_unknown_imag] +
1858 d_gamma_con_n[global_unknown_imag]);
1867 Gamma_at_gauss_point[el_pt] = gamma_vector;
1868 D_Gamma_at_gauss_point[el_pt] = d_gamma_vector;
1876 template<
class ELEMENT>
1884 ELEMENT* elem_pt =
new ELEMENT;
1886 if (elem_pt->dim() == 3)
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";
1933 error_string +=
"HelmholtzEquations<1>\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";
1961 error_string +=
"HelmholtzEquations<2>\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";
1989 error_string +=
"HelmholtzEquations<3>\n.";
1990 error_string +=
"If you desire this functionality, you must "
1991 "implement it yourself\n";
2006 std::ostringstream error_stream;
2007 error_stream <<
"Dimension of node is " <<
Dim
2008 <<
". It should be 1,2, or 3!" << std::endl;
AnnoyingScalar atan2(const AnnoyingScalar &y, const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:139
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
@ R
Definition: StatisticsVector.h:21
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
double nodal_position(const unsigned &n, const unsigned &i) const
Definition: elements.h:2317
virtual void dshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Definition: elements.h:1981
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
Definition: helmholtz_bc_elements.h:639
void fill_in_generic_residual_contribution_helmholtz_abc(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Definition: helmholtz_bc_elements.h:691
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: helmholtz_bc_elements.h:672
unsigned * ABC_order_pt
Pointer to order of absorbing boundary condition.
Definition: helmholtz_bc_elements.h:1112
double * Outer_radius_pt
Pointer to radius of outer boundary (must be a circle!)
Definition: helmholtz_bc_elements.h:1109
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector.
Definition: helmholtz_bc_elements.h:662
HelmholtzAbsorbingBCElement(FiniteElement *const &bulk_el_pt, const int &face_index)
Definition: helmholtz_bc_elements.h:643
double *& outer_radius_pt()
Get pointer to radius of outer boundary (must be a cirle)
Definition: helmholtz_bc_elements.h:682
unsigned *& abc_order_pt()
Pointer to order of absorbing boundary condition.
Definition: helmholtz_bc_elements.h:655
Definition: helmholtz_bc_elements.h:168
double test_only(const Vector< double > &s, Shape &test) const
Definition: helmholtz_bc_elements.h:504
void output(std::ostream &outfile, const unsigned &n_plot)
Definition: helmholtz_bc_elements.h:218
double global_power_contribution()
Definition: helmholtz_bc_elements.h:248
double global_power_contribution(std::ofstream &outfile)
Definition: helmholtz_bc_elements.h:259
HelmholtzBCElementBase()
Broken empty constructor.
Definition: helmholtz_bc_elements.h:176
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
Broken assignment operator.
Definition: helmholtz_bc_elements.h:201
void output(FILE *file_pt)
Definition: helmholtz_bc_elements.h:225
void output(std::ostream &outfile)
Definition: helmholtz_bc_elements.h:211
virtual std::complex< unsigned > u_index_helmholtz() const
Definition: helmholtz_bc_elements.h:240
HelmholtzBCElementBase(const HelmholtzBCElementBase &dummy)=delete
Broken copy constructor.
double d_shape_and_test_local(const Vector< double > &s, Shape &psi, Shape &test, DShape &dpsi_ds, DShape &dtest_ds) const
Definition: helmholtz_bc_elements.h:517
void compute_contribution_to_fourier_components(Vector< std::complex< double >> &a_coeff_pos, Vector< std::complex< double >> &a_coeff_neg)
Definition: helmholtz_bc_elements.h:389
void output(FILE *file_pt, const unsigned &n_plot)
Definition: helmholtz_bc_elements.h:233
unsigned Dim
The spatial dimension of the problem.
Definition: helmholtz_bc_elements.h:547
std::complex< unsigned > U_index_helmholtz
Definition: helmholtz_bc_elements.h:544
Definition: helmholtz_bc_elements.h:1121
void fill_in_generic_residual_contribution_helmholtz_DtN_bc(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Definition: helmholtz_bc_elements.h:1228
HelmholtzDtNMesh< ELEMENT > * outer_boundary_mesh_pt() const
Definition: helmholtz_bc_elements.h:1163
HelmholtzDtNBoundaryElement(FiniteElement *const &bulk_el_pt, const int &face_index)
Definition: helmholtz_bc_elements.h:1125
void set_outer_boundary_mesh_pt(HelmholtzDtNMesh< ELEMENT > *mesh_pt)
Set mesh of all DtN boundary condition elements.
Definition: helmholtz_bc_elements.h:1169
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the element's contribution to its residual vector.
Definition: helmholtz_bc_elements.h:1132
HelmholtzDtNMesh< ELEMENT > * Outer_boundary_mesh_pt
Definition: helmholtz_bc_elements.h:1443
void complete_setup_of_dependencies()
Definition: helmholtz_bc_elements.h:1178
void compute_gamma_contribution(const double &phi, const int &n, std::complex< double > &gamma_con, std::map< unsigned, std::complex< double >> &d_gamma_con)
Definition: helmholtz_bc_elements.h:1459
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: helmholtz_bc_elements.h:1142
Definition: helmholtz_bc_elements.h:562
std::map< FiniteElement *, Vector< std::complex< double > > > Gamma_at_gauss_point
Definition: helmholtz_bc_elements.h:618
std::map< FiniteElement *, Vector< std::map< unsigned, std::complex< double > > > > D_Gamma_at_gauss_point
Definition: helmholtz_bc_elements.h:624
Vector< std::complex< double > > & gamma_at_gauss_point(FiniteElement *el_pt)
Definition: helmholtz_bc_elements.h:582
unsigned Nfourier_terms
Nbr of Fourier terms used in the Gamma computation.
Definition: helmholtz_bc_elements.h:613
void setup_gamma()
of the mesh's constituent elements
Definition: helmholtz_bc_elements.h:1674
void compute_fourier_components(Vector< std::complex< double >> &a_coeff_pos, Vector< std::complex< double >> &a_coeff_neg)
Definition: helmholtz_bc_elements.h:1621
unsigned & nfourier_terms()
Definition: helmholtz_bc_elements.h:603
double Outer_radius
Outer radius.
Definition: helmholtz_bc_elements.h:610
HelmholtzDtNMesh(const double &outer_radius, const unsigned &nfourier_terms)
Definition: helmholtz_bc_elements.h:566
Vector< std::map< unsigned, std::complex< double > > > & d_gamma_at_gauss_point(FiniteElement *el_pt)
Definition: helmholtz_bc_elements.h:589
double & outer_radius()
The outer radius.
Definition: helmholtz_bc_elements.h:596
Definition: helmholtz_elements.h:56
virtual std::complex< unsigned > u_index_helmholtz() const
Broken assignment operator.
Definition: helmholtz_elements.h:80
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
Definition: oomph_definitions.h:267
Definition: refineable_elements.h:97
Definition: oomph-lib/src/generic/Vector.h:58
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
int cbessjyna(int n, complex< double > z, int &nm, complex< double > *cj, complex< double > *cy, complex< double > *cjp, complex< double > *cyp)
Definition: crbond_bessel.cc:1858
int bessjyna(int n, double x, int &nm, double *jn, double *yn, double *jnp, double *ynp)
Definition: crbond_bessel.cc:852
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 exp(const bfloat16 &a)
Definition: BFloat16.h:615
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
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
static const unsigned Dim
Problem dimension.
Definition: two_d_tilted_square.cc:62
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
void CHankel_first(const unsigned &n, const std::complex< double > &x, Vector< std::complex< double >> &h, Vector< std::complex< double >> &hp)
Definition: helmholtz_bc_elements.h:95
void Hankel_first(const unsigned &n, const double &x, Vector< std::complex< double >> &h, Vector< std::complex< double >> &hp)
Definition: helmholtz_bc_elements.h:62
const double Pi
50 digits from maple
Definition: oomph_utilities.h:157
@ W
Definition: quadtree.h:63
double Tol
Definition: helmholtz_bc_elements.h:1607
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