44 template<
unsigned DIM>
52 unsigned n_node = nnode();
55 Shape psi(n_node), test(n_node);
56 DShape dpsidx(n_node,DIM), dtestdx(n_node,DIM);
59 unsigned n_intpt = integral_pt()->nweight();
62 int local_eqn_real=0, local_unknown_real=0;
63 int local_eqn_imag=0, local_unknown_imag=0;
66 HangInfo *hang_info_pt=0, *hang_info2_pt=0;
69 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
72 double w = integral_pt()->weight(ipt);
76 this->dshape_and_dtest_eulerian_at_knot_helmholtz(ipt,psi,dpsidx,
83 std::complex<double> interpolated_u(0.0,0.0);
91 for(
unsigned l=0;l<n_node;l++)
94 for(
unsigned j=0;j<DIM;j++)
96 interpolated_x[j] += nodal_position(l,j)*psi(l);
99 const std::complex<double> u_value(
100 nodal_value(l,this->u_index_helmholtz().real()),
101 nodal_value(l,this->u_index_helmholtz().imag()));
103 interpolated_u += u_value*psi(l);
106 for(
unsigned j=0;j<DIM;j++)
108 interpolated_dudx[j] += u_value*dpsidx(l,j);
113 std::complex<double> source(0.0,0.0);
114 this->get_source_helmholtz(ipt,interpolated_x,source);
120 for(
unsigned l=0;l<n_node;l++)
124 unsigned n_master=1;
double hang_weight=1.0;
127 bool is_node_hanging = this->node_pt(l)->is_hanging();
132 hang_info_pt = this->node_pt(l)->hanging_pt();
133 n_master = hang_info_pt->
nmaster();
142 for(
unsigned m=0;m<n_master;m++)
149 local_eqn_real=this->local_hang_eqn(hang_info_pt->
master_node_pt(m),
150 this->u_index_helmholtz().real());
151 local_eqn_imag=this->local_hang_eqn(hang_info_pt->
master_node_pt(m),
152 this->u_index_helmholtz().imag());
161 local_eqn_real=this->nodal_local_eqn(l,this->u_index_helmholtz().real());
162 local_eqn_imag=this->nodal_local_eqn(l,this->u_index_helmholtz().imag());
169 if(local_eqn_real >= 0)
172 residuals[local_eqn_real] +=
173 (source.real()-this->k_squared()*interpolated_u.real())*
174 test(l)*W*hang_weight;
177 for(
unsigned k=0;k<DIM;k++)
179 residuals[local_eqn_real] +=
180 interpolated_dudx[k].real()*dtestdx(l,k)*W*hang_weight;
188 unsigned n_master2=1;
double hang_weight2=1.0;
191 for(
unsigned l2=0;l2<n_node;l2++)
194 bool is_node2_hanging = this->node_pt(l2)->is_hanging();
199 hang_info2_pt = this->node_pt(l2)->hanging_pt();
200 n_master2 = hang_info2_pt->nmaster();
209 for(
unsigned m2=0;m2<n_master2;m2++)
217 this->local_hang_eqn(hang_info2_pt->master_node_pt(m2),
218 this->u_index_helmholtz().real());
221 hang_weight2 = hang_info2_pt->master_weight(m2);
228 this->nodal_local_eqn(l2,this->u_index_helmholtz().real());
235 if(local_unknown_real >= 0)
238 for(
unsigned i=0;
i<DIM;
i++)
240 jacobian(local_eqn_real,local_unknown_real) +=
241 dpsidx(l2,
i)*dtestdx(l,
i)*W*hang_weight*hang_weight2;
245 jacobian(local_eqn_real,local_unknown_real) -=
246 this->k_squared()*psi(l2)*test(l)*W*
247 hang_weight*hang_weight2;
255 if(local_eqn_imag >= 0)
258 residuals[local_eqn_imag] +=
259 (source.imag()-this->k_squared()*interpolated_u.imag())*
260 test(l)*W*hang_weight;
263 for(
unsigned k=0;k<DIM;k++)
265 residuals[local_eqn_imag] +=
266 interpolated_dudx[k].imag()*dtestdx(l,k)*W*hang_weight;
274 unsigned n_master2=1;
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();
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++)
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);
315 this->nodal_local_eqn(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*hang_weight2;
331 jacobian(local_eqn_imag,local_unknown_imag) -=
332 this->k_squared()*psi(l2)*test(l)*W*
333 hang_weight*hang_weight2;
double const & master_weight(const unsigned &i) const
Return weight for dofs on i-th master node.
unsigned nmaster() const
Return the number of master nodes.
Node *const & master_node_pt(const unsigned &i) const
Return a pointer to the i-th master node.
Class that contains data for hanging 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...