37 template<
class ELEMENT>
57 "YoungLaplaceContactAngleElement only work with 2D nodes",
58 OOMPH_CURRENT_FUNCTION,
59 OOMPH_EXCEPTION_LOCATION);
68 template<
class ELEMENT>
73 unsigned n_node = nnode();
79 unsigned n_intpt = integral_pt()->nweight();
91 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
94 s[0] = integral_pt()->knot(ipt, 0);
97 double w = integral_pt()->weight(ipt);
100 shape_at_knot(ipt, psi);
103 double cos_gamma = prescribed_cos_gamma();
110 contact_line_vectors(
s, tangent, normal, spine, norm_of_drds);
117 ELEMENT::cross_product(spine, tangent, wall_normal);
120 double norm = ELEMENT::two_norm(wall_normal);
121 for (
unsigned i = 0;
i < 3;
i++) wall_normal[
i] /= norm;
126 ELEMENT::cross_product(
127 tangent, wall_normal, normal_to_contact_line_parallel_to_wall);
130 ELEMENT::scalar_product(spine, normal_to_contact_line_parallel_to_wall);
136 for (
unsigned l = 0; l < n_node; l++)
138 local_eqn = u_local_eqn(l);
143 residuals[local_eqn] -= beta * cos_gamma * psi[l] * norm_of_drds * w;
153 template<
class ELEMENT>
158 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(this->bulk_element_pt());
160 double cos_gamma = 0.0;
163 if (bulk_elem_pt->use_spines())
170 contact_line_vectors(
s, tangent, normal, spine, norm_of_drds);
177 ELEMENT::cross_product(axe_ez, tangent, wall_normal);
181 for (
unsigned i = 0;
i < 3;
i++) norm += wall_normal[
i] * wall_normal[
i];
182 for (
unsigned i = 0;
i < 3;
i++)
184 wall_normal[
i] /= sqrt(norm);
190 ELEMENT::cross_product(tangent, wall_normal, aux);
193 cos_gamma = ELEMENT::scalar_product(aux, normal);
203 unsigned nnode_bulk = bulk_elem_pt->nnode();
208 unsigned dim_bulk = bulk_elem_pt->dim();
213 "YoungLaplaceContactAngleElements only work with 2D bulk elements",
214 OOMPH_CURRENT_FUNCTION,
215 OOMPH_EXCEPTION_LOCATION);
220 Shape psi(nnode_bulk);
221 DShape dpsidzeta(nnode_bulk, 2);
226 (void)bulk_elem_pt->dshape_eulerian(s_bulk, psi, dpsidzeta);
234 for (
unsigned l = 0; l < nnode_bulk; l++)
237 for (
unsigned j = 0; j < 2; j++)
239 gradient_u[j] += bulk_elem_pt->u(l) * dpsidzeta(l, j);
245 outer_unit_normal(
s, outer_normal);
248 double gradient_norm_2 =
249 ELEMENT::two_norm(gradient_u) * ELEMENT::two_norm(gradient_u);
250 cos_gamma = ELEMENT::scalar_product(gradient_u, outer_normal) /
251 sqrt(1 + gradient_norm_2);
264 template<
class ELEMENT>
270 double& norm_of_drds)
273 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(this->bulk_element_pt());
276 unsigned dim_bulk = bulk_elem_pt->dim();
282 "YoungLaplaceContactAngleElements only work with 2D bulk elements",
283 OOMPH_CURRENT_FUNCTION,
284 OOMPH_EXCEPTION_LOCATION);
289 unsigned s_fixed_index_in_bulk;
292 this->get_ds_bulk_ds_face(
s, ds_bulk_ds_face, s_fixed_index_in_bulk);
298 unsigned nnode_bulk = bulk_elem_pt->nnode();
302 Shape psi_bulk(nnode_bulk);
303 DShape dpsi_bulk(nnode_bulk, dim_bulk);
304 bulk_elem_pt->dshape_local(s_bulk, psi_bulk, dpsi_bulk);
307 double interpolated_u = 0.0;
310 double interpolated_du_ds_tangent = 0.0;
311 double interpolated_du_ds_pseudo_normal = 0.0;
324 for (
unsigned l = 0; l < nnode_bulk; l++)
326 interpolated_u += bulk_elem_pt->u(l) * psi_bulk(l);
330 for (
unsigned i = 0;
i < dim_bulk;
i++)
332 aux += dpsi_bulk(l,
i) * ds_bulk_ds_face(
i, 0);
334 interpolated_du_ds_tangent += bulk_elem_pt->u(l) * aux;
338 interpolated_du_ds_pseudo_normal +=
339 bulk_elem_pt->u(l) * dpsi_bulk(l, s_fixed_index_in_bulk);
342 for (
unsigned j = 0; j < dim_bulk; j++)
344 interpolated_zeta[j] +=
345 bulk_elem_pt->nodal_position(l, j) * psi_bulk(l);
349 for (
unsigned i = 0;
i < dim_bulk;
i++)
351 aux += dpsi_bulk(l,
i) * ds_bulk_ds_face(
i, 0);
353 interpolated_dzeta_ds_tangent[j] +=
354 bulk_elem_pt->nodal_position(l, j) * aux;
358 interpolated_dzeta_ds_pseudo_normal[j] +=
359 bulk_elem_pt->nodal_position(l, j) *
360 dpsi_bulk(l, s_fixed_index_in_bulk);
367 double tang_norm = 0.0;
368 double aux_norm = 0.0;
370 if (bulk_elem_pt->use_spines())
375 ELEMENT::allocate_vector_of_vectors(2, 3, dspine);
377 ELEMENT::allocate_vector_of_vectors(2, 3, dspine_base);
378 bulk_elem_pt->get_spine(interpolated_zeta, spine, dspine);
379 bulk_elem_pt->get_spine_base(interpolated_zeta, spine_base, dspine_base);
387 for (
unsigned i = 0;
i < 3;
i++)
389 dspine_ds_tangent[
i] +=
390 dspine[0][
i] * interpolated_dzeta_ds_tangent[0] +
391 dspine[1][
i] * interpolated_dzeta_ds_tangent[1];
393 dspine_base_ds_tangent[
i] +=
394 dspine_base[0][
i] * interpolated_dzeta_ds_tangent[0] +
395 dspine_base[1][
i] * interpolated_dzeta_ds_tangent[1];
397 dspine_ds_pseudo_normal[
i] +=
398 dspine[0][
i] * interpolated_dzeta_ds_pseudo_normal[0] +
399 dspine[1][
i] * interpolated_dzeta_ds_pseudo_normal[1];
401 dspine_base_ds_pseudo_normal[
i] +=
402 dspine_base[0][
i] * interpolated_dzeta_ds_pseudo_normal[0] +
403 dspine_base[1][
i] * interpolated_dzeta_ds_pseudo_normal[1];
408 for (
unsigned i = 0;
i < 3;
i++)
410 tangent[
i] = dspine_base_ds_tangent[
i] +
411 interpolated_du_ds_tangent * spine[
i] +
412 interpolated_u * dspine_ds_tangent[
i];
413 tang_norm += tangent[
i] * tangent[
i];
416 aux_vector[
i] = dspine_base_ds_pseudo_normal[
i] +
417 interpolated_du_ds_pseudo_normal * spine[
i] +
418 interpolated_u * dspine_ds_pseudo_normal[
i];
419 aux_norm += aux_vector[
i] * aux_vector[
i];
426 for (
unsigned i = 0;
i < 2;
i++)
428 tangent[
i] = interpolated_dzeta_ds_tangent[
i];
429 tang_norm += tangent[
i] * tangent[
i];
430 aux_vector[
i] = interpolated_dzeta_ds_pseudo_normal[
i];
431 aux_norm += aux_vector[
i] * aux_vector[
i];
434 tangent[2] = interpolated_du_ds_tangent;
435 tang_norm += tangent[2] * tangent[2];
436 aux_vector[2] = interpolated_du_ds_pseudo_normal;
437 aux_norm += aux_vector[2] * aux_vector[2];
441 norm_of_drds = sqrt(tang_norm);
444 double tang_norm_fact = 1.0 / sqrt(tang_norm);
445 double aux_norm_fact = 1.0 / sqrt(aux_norm);
446 for (
unsigned i = 0;
i < 3;
i++)
448 tangent[
i] *= tang_norm_fact;
449 aux_vector[
i] *= aux_norm_fact;
456 ELEMENT::cross_product(tangent, aux_vector, meniscus_normal);
459 double men_norm_fact = 0.0;
460 for (
unsigned i = 0;
i < 3;
i++)
462 men_norm_fact += meniscus_normal[
i] * meniscus_normal[
i];
466 double sign = -double(normal_sign());
467 for (
unsigned i = 0;
i < 3;
i++)
469 meniscus_normal[
i] *= sign / sqrt(men_norm_fact);
474 ELEMENT::cross_product(meniscus_normal, tangent, normal);
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
FaceElements are elements that coincide with the faces of higher-dimensional "bulk" elements....
int & face_index()
Index of the face (a number that uniquely identifies the face in the element)
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
A general Finite Element class.
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 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 ndim() const
Return (Eulerian) spatial dimension of the node.
An OomphLibError object which should be thrown when an run-time error is encountered....
Refineable version of 2D QYoungLaplaceElement elements.
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...