42 template<
class ELEMENT>
45 const int &face_index) :
64 "YoungLaplaceContactAngleElement only work with 2D nodes",
65 OOMPH_CURRENT_FUNCTION,
66 OOMPH_EXCEPTION_LOCATION);
79 template<
class ELEMENT>
84 unsigned n_node =
nnode();
102 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
128 ELEMENT::cross_product(spine,tangent,wall_normal);
131 double norm=ELEMENT::two_norm(wall_normal);
132 for (
unsigned i=0;
i<3;
i++) wall_normal[
i]/=norm;
137 ELEMENT::cross_product(tangent,wall_normal,
138 normal_to_contact_line_parallel_to_wall);
140 double beta=ELEMENT::scalar_product(spine,
141 normal_to_contact_line_parallel_to_wall);
147 for(
unsigned l=0;l<n_node;l++)
154 residuals[local_eqn] -= beta*cos_gamma*psi[l]*norm_of_drds*w;
167 template<
class ELEMENT>
172 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(this->
bulk_element_pt());
174 double cos_gamma=0.0;
177 if ( bulk_elem_pt->use_spines() )
191 ELEMENT::cross_product(axe_ez,tangent,wall_normal);
195 for (
unsigned i=0;
i<3;
i++) norm+=wall_normal[
i]*wall_normal[
i];
196 for (
unsigned i=0;
i<3;
i++)
198 wall_normal[
i]/=sqrt(norm);
204 ELEMENT::cross_product(tangent,wall_normal,aux);
207 cos_gamma=ELEMENT::scalar_product(aux,normal);
219 unsigned nnode_bulk=bulk_elem_pt->nnode();
224 unsigned dim_bulk=bulk_elem_pt->dim();
229 "YoungLaplaceContactAngleElements only work with 2D bulk elements",
230 OOMPH_CURRENT_FUNCTION,
231 OOMPH_EXCEPTION_LOCATION);
236 Shape psi(nnode_bulk);
237 DShape dpsidzeta(nnode_bulk,2);
242 (void)bulk_elem_pt->dshape_eulerian(s_bulk,psi,dpsidzeta);
250 for(
unsigned l=0;l<nnode_bulk;l++)
253 for(
unsigned j=0;j<2;j++)
254 { gradient_u[j]+= bulk_elem_pt->u(l)*dpsidzeta(l,j); }
262 double gradient_norm_2=
263 ELEMENT::two_norm(gradient_u)*
264 ELEMENT::two_norm(gradient_u);
265 cos_gamma=ELEMENT::scalar_product(gradient_u,outer_normal)/
266 sqrt(1+gradient_norm_2);
282 template<
class ELEMENT>
288 double& norm_of_drds)
292 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(this->
bulk_element_pt());
295 unsigned dim_bulk=bulk_elem_pt->dim();
301 "YoungLaplaceContactAngleElements only work with 2D bulk elements",
302 OOMPH_CURRENT_FUNCTION,
303 OOMPH_EXCEPTION_LOCATION);
308 unsigned s_fixed_index_in_bulk;
312 s_fixed_index_in_bulk);
318 unsigned nnode_bulk=bulk_elem_pt->nnode();
322 Shape psi_bulk(nnode_bulk);
323 DShape dpsi_bulk(nnode_bulk,dim_bulk);
324 bulk_elem_pt->dshape_local(s_bulk,psi_bulk,dpsi_bulk);
327 double interpolated_u=0.0;
330 double interpolated_du_ds_tangent=0.0;
331 double interpolated_du_ds_pseudo_normal=0.0;
344 for(
unsigned l=0;l<nnode_bulk;l++)
346 interpolated_u+=bulk_elem_pt->u(l)*psi_bulk(l);
350 for (
unsigned i=0;
i<dim_bulk;
i++)
352 aux+=dpsi_bulk(l,
i)*ds_bulk_ds_face(
i,0);
354 interpolated_du_ds_tangent+=bulk_elem_pt->u(l)*aux;
358 interpolated_du_ds_pseudo_normal +=
359 bulk_elem_pt->u(l)*dpsi_bulk(l,s_fixed_index_in_bulk);
362 for(
unsigned j=0;j<dim_bulk;j++)
364 interpolated_zeta[j]+=bulk_elem_pt->nodal_position(l,j)*psi_bulk(l);
368 for (
unsigned i=0;
i<dim_bulk;
i++)
370 aux+=dpsi_bulk(l,
i)*ds_bulk_ds_face(
i,0);
372 interpolated_dzeta_ds_tangent[j] +=
373 bulk_elem_pt->nodal_position(l,j)*aux;
377 interpolated_dzeta_ds_pseudo_normal[j] +=
378 bulk_elem_pt->nodal_position(l,j)*dpsi_bulk(l,s_fixed_index_in_bulk);
386 double tang_norm=0.0;
389 if ( bulk_elem_pt->use_spines() )
394 ELEMENT::allocate_vector_of_vectors(2,3,dspine);
396 ELEMENT::allocate_vector_of_vectors(2,3,dspine_base);
397 bulk_elem_pt->get_spine(interpolated_zeta,spine,dspine);
398 bulk_elem_pt->get_spine_base(interpolated_zeta,spine_base,dspine_base);
406 for (
unsigned i=0;
i<3;
i++)
409 dspine_ds_tangent[
i]+=
410 dspine[0][
i]*interpolated_dzeta_ds_tangent[0]+
411 dspine[1][
i]*interpolated_dzeta_ds_tangent[1];
413 dspine_base_ds_tangent[
i]+=
414 dspine_base[0][
i]*interpolated_dzeta_ds_tangent[0]+
415 dspine_base[1][
i]*interpolated_dzeta_ds_tangent[1];
417 dspine_ds_pseudo_normal[
i]+=
418 dspine[0][
i]*interpolated_dzeta_ds_pseudo_normal[0]+
419 dspine[1][
i]*interpolated_dzeta_ds_pseudo_normal[1];
421 dspine_base_ds_pseudo_normal[
i]+=
422 dspine_base[0][
i]*interpolated_dzeta_ds_pseudo_normal[0]+
423 dspine_base[1][
i]*interpolated_dzeta_ds_pseudo_normal[1];
428 for (
unsigned i=0;
i<3;
i++)
431 dspine_base_ds_tangent[
i]+interpolated_du_ds_tangent*spine[
i]+
432 interpolated_u*dspine_ds_tangent[
i];
433 tang_norm+=tangent[
i]*tangent[
i];
437 dspine_base_ds_pseudo_normal[
i]+
438 interpolated_du_ds_pseudo_normal*spine[
i]+
439 interpolated_u*dspine_ds_pseudo_normal[
i];
440 aux_norm+=aux_vector[
i]*aux_vector[
i];
448 for(
unsigned i=0;
i<2;
i++)
450 tangent[
i]= interpolated_dzeta_ds_tangent[
i];
451 tang_norm+=tangent[
i]*tangent[
i];
452 aux_vector[
i]= interpolated_dzeta_ds_pseudo_normal[
i];
453 aux_norm+=aux_vector[
i]*aux_vector[
i];
457 tangent[2]=interpolated_du_ds_tangent;
458 tang_norm+=tangent[2]*tangent[2];
459 aux_vector[2]=interpolated_du_ds_pseudo_normal;
460 aux_norm+=aux_vector[2]*aux_vector[2];
465 norm_of_drds=sqrt(tang_norm);
468 double tang_norm_fact=1.0/sqrt(tang_norm);
469 double aux_norm_fact=1.0/sqrt(aux_norm);
470 for (
unsigned i=0;
i<3;
i++)
472 tangent[
i]*=tang_norm_fact;
473 aux_vector[
i]*=aux_norm_fact;
480 ELEMENT::cross_product(tangent,aux_vector,meniscus_normal);
483 double men_norm_fact=0.0;
484 for (
unsigned i=0;
i<3;
i++)
486 men_norm_fact+=meniscus_normal[
i]*meniscus_normal[
i];
491 for (
unsigned i=0;
i<3;
i++)
493 meniscus_normal[
i]*=sign/sqrt(men_norm_fact);
498 ELEMENT::cross_product(meniscus_normal,tangent,normal);
void get_ds_bulk_ds_face(const Vector< double > &s, DenseMatrix< double > &dsbulk_dsface, unsigned &interior_direction) const
Calculate the derivatives of the local coordinates in the bulk element with respect to the local coor...
void outer_unit_normal(const Vector< double > &s, Vector< double > &unit_normal) const
Compute outer unit normal at the specified local coordinate.
A general Finite Element class.
virtual double weight(const unsigned &i) const =0
Return weight of i-th integration point.
int & normal_sign()
Sign of outer unit normal (relative to cross-products of tangent vectors in the corresponding "bulk" ...
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
void interpolated_zeta(const Vector< double > &s, Vector< double > &zeta) const
Calculate the interpolated value of zeta, the intrinsic coordinate of the element when viewed as a co...
virtual void shape_at_knot(const unsigned &ipt, Shape &psi) const
Return the geometric shape function at the ipt-th integration point.
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
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 nnode() const
Return the number of nodes.
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...