37 template<
unsigned DIM>
45 unsigned n_node = nnode();
48 Shape psi(n_node), test(n_node);
49 DShape dpsidx(n_node, DIM), dtestdx(n_node, DIM);
52 unsigned n_intpt = integral_pt()->nweight();
55 int local_eqn_real = 0, local_unknown_real = 0;
56 int local_eqn_imag = 0, local_unknown_imag = 0;
59 HangInfo *hang_info_pt = 0, *hang_info2_pt = 0;
62 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
65 double w = integral_pt()->weight(ipt);
68 double J = this->dshape_and_dtest_eulerian_at_knot_helmholtz(
69 ipt, psi, dpsidx, test, dtestdx);
75 std::complex<double> interpolated_u(0.0, 0.0);
83 for (
unsigned l = 0; l < n_node; l++)
86 for (
unsigned j = 0; j < DIM; j++)
88 interpolated_x[j] += nodal_position(l, j) * psi(l);
91 const std::complex<double> u_value(
92 nodal_value(l, this->u_index_helmholtz().real()),
93 nodal_value(l, this->u_index_helmholtz().imag()));
95 interpolated_u += u_value * psi(l);
98 for (
unsigned j = 0; j < DIM; j++)
100 interpolated_dudx[j] += u_value * dpsidx(l, j);
105 std::complex<double> source(0.0, 0.0);
106 this->get_source_helmholtz(ipt, interpolated_x, source);
112 for (
unsigned l = 0; l < n_node; l++)
116 unsigned n_master = 1;
117 double hang_weight = 1.0;
120 bool is_node_hanging = this->node_pt(l)->is_hanging();
125 hang_info_pt = this->node_pt(l)->hanging_pt();
126 n_master = hang_info_pt->
nmaster();
135 for (
unsigned m = 0; m < n_master; m++)
144 this->u_index_helmholtz().real());
147 this->u_index_helmholtz().imag());
157 this->nodal_local_eqn(l, this->u_index_helmholtz().real());
159 this->nodal_local_eqn(l, this->u_index_helmholtz().imag());
166 if (local_eqn_real >= 0)
169 residuals[local_eqn_real] +=
170 (source.real() - this->k_squared() * interpolated_u.real()) *
171 test(l) *
W * hang_weight;
174 for (
unsigned k = 0; k < DIM; k++)
176 residuals[local_eqn_real] +=
177 interpolated_dudx[k].real() * dtestdx(l, k) *
W * hang_weight;
185 unsigned n_master2 = 1;
186 double hang_weight2 = 1.0;
189 for (
unsigned l2 = 0; l2 < n_node; l2++)
192 bool is_node2_hanging = this->node_pt(l2)->is_hanging();
195 if (is_node2_hanging)
197 hang_info2_pt = this->node_pt(l2)->hanging_pt();
198 n_master2 = hang_info2_pt->nmaster();
207 for (
unsigned m2 = 0; m2 < n_master2; m2++)
211 if (is_node2_hanging)
215 this->local_hang_eqn(hang_info2_pt->master_node_pt(m2),
216 this->u_index_helmholtz().real());
219 hang_weight2 = hang_info2_pt->master_weight(m2);
225 local_unknown_real = this->nodal_local_eqn(
226 l2, this->u_index_helmholtz().real());
233 if (local_unknown_real >= 0)
236 for (
unsigned i = 0;
i < DIM;
i++)
238 jacobian(local_eqn_real, local_unknown_real) +=
239 dpsidx(l2,
i) * dtestdx(l,
i) *
W * hang_weight *
244 jacobian(local_eqn_real, local_unknown_real) -=
245 this->k_squared() * psi(l2) * test(l) *
W * hang_weight *
254 if (local_eqn_imag >= 0)
257 residuals[local_eqn_imag] +=
258 (source.imag() - this->k_squared() * interpolated_u.imag()) *
259 test(l) *
W * hang_weight;
262 for (
unsigned k = 0; k < DIM; k++)
264 residuals[local_eqn_imag] +=
265 interpolated_dudx[k].imag() * dtestdx(l, k) *
W * hang_weight;
273 unsigned n_master2 = 1;
274 double hang_weight2 = 1.0;
277 for (
unsigned l2 = 0; l2 < n_node; l2++)
280 bool is_node2_hanging = this->node_pt(l2)->is_hanging();
283 if (is_node2_hanging)
285 hang_info2_pt = this->node_pt(l2)->hanging_pt();
286 n_master2 = hang_info2_pt->nmaster();
295 for (
unsigned m2 = 0; m2 < n_master2; m2++)
299 if (is_node2_hanging)
303 this->local_hang_eqn(hang_info2_pt->master_node_pt(m2),
304 this->u_index_helmholtz().imag());
307 hang_weight2 = hang_info2_pt->master_weight(m2);
314 local_unknown_imag = this->nodal_local_eqn(
315 l2, this->u_index_helmholtz().imag());
321 if (local_unknown_imag >= 0)
324 for (
unsigned i = 0;
i < DIM;
i++)
326 jacobian(local_eqn_imag, local_unknown_imag) +=
327 dpsidx(l2,
i) * dtestdx(l,
i) *
W * hang_weight *
332 jacobian(local_eqn_imag, local_unknown_imag) -=
333 this->k_squared() * psi(l2) * test(l) *
W * hang_weight *
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
Class that contains data for hanging nodes.
double const & master_weight(const unsigned &i) const
Return weight for dofs on i-th master node.
Node *const & master_node_pt(const unsigned &i) const
Return a pointer to the i-th master node.
unsigned nmaster() const
Return the number of master nodes.
void fill_in_generic_residual_contribution_helmholtz(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Add element's contribution to elemental residual vector and/or Jacobian matrix flag=1: compute both f...
Refineable version of 2D QHelmholtzElement elements.
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...