45 const unsigned n_node =
nnode();
54 unsigned u_nodal_index[3];
55 for (
unsigned i = 0;
i < 3; ++
i)
66 bool pressure_dof_is_hanging[n_pres];
71 for (
unsigned l = 0; l < n_pres; ++l)
79 for (
unsigned l = 0; l < n_pres; ++l)
81 pressure_dof_is_hanging[l] =
false;
87 Shape psif(n_node), testf(n_node);
88 DShape dpsifdx(n_node, 2), dtestfdx(n_node, 2);
91 Shape psip(n_pres), testp(n_pres);
102 const double scaled_re =
re() * dens_ratio;
103 const double scaled_re_st =
re_st() * dens_ratio;
104 const double scaled_re_inv_ro =
re_invro() * dens_ratio;
110 int local_eqn = 0, local_unknown = 0;
113 HangInfo *hang_info_pt = 0, *hang_info2_pt = 0;
116 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
119 for (
unsigned i = 0;
i < 2;
i++)
129 ipt, psif, dpsifdx, testf, dtestfdx);
139 double interpolated_p = 0.0;
147 for (
unsigned l = 0; l < n_pres; l++)
155 for (
unsigned l = 0; l < n_node; l++)
158 double psi_ = psif(l);
160 for (
unsigned i = 0;
i < 2;
i++)
166 for (
unsigned i = 0;
i < 3;
i++)
168 const double u_value = this->
nodal_value(l, u_nodal_index[
i]);
169 interpolated_u[
i] += u_value * psi_;
173 for (
unsigned j = 0; j < 2; j++)
175 interpolated_dudx(
i, j) += u_value * dpsifdx(l, j);
184 "ALE is not properly implemented for Refineable Spherical NS yet",
185 OOMPH_CURRENT_FUNCTION,
186 OOMPH_EXCEPTION_LOCATION);
189 for (
unsigned i = 0;
i < 2;
i++)
207 const double r2 = r * r;
211 const double cot_theta = cos_theta / sin_theta;
213 const double u_r = interpolated_u[0];
214 const double u_theta = interpolated_u[1];
215 const double u_phi = interpolated_u[2];
225 unsigned n_master = 1;
226 double hang_weight = 1.0;
230 for (
unsigned l = 0; l < n_node; l++)
241 n_master = hang_info_pt->
nmaster();
250 for (
unsigned m = 0; m < n_master; m++)
253 for (
unsigned i = 0;
i < 2 + 1;
i++)
286 double conv = r * u_r * interpolated_dudx(0, 0);
289 conv += u_theta * interpolated_dudx(0, 1);
292 conv -= (u_theta * u_theta + u_phi * u_phi);
295 sum += (scaled_re_st * dudt[0] * r2 + scaled_re * r * conv) *
296 sin_theta * testf(l);
299 sum -= r2 * sin_theta * body_force[0] * testf(l);
302 sum -= 2.0 * scaled_re_inv_ro * sin_theta * u_phi * r2 *
303 sin_theta * testf(l);
306 sum += (-interpolated_p + 2 * interpolated_dudx(0, 0)) * r2 *
307 sin_theta * dtestfdx(l, 0);
310 sum += (r * interpolated_dudx(1, 0) - u_theta +
311 interpolated_dudx(0, 1)) *
312 sin_theta * dtestfdx(l, 1);
316 ((-r * interpolated_p + +interpolated_dudx(1, 1) +
319 u_theta * cos_theta) *
329 (u_r * interpolated_dudx(1, 0) * r +
330 u_theta * interpolated_dudx(1, 1) + u_r * u_theta) *
332 u_phi * u_phi * cos_theta;
336 sum += (scaled_re_st * r2 * sin_theta * dudt[1] +
337 scaled_re * r * conv) *
341 sum -= r2 * sin_theta * body_force[1] * testf(l);
344 sum -= 2.0 * scaled_re_inv_ro * cos_theta * u_phi * r2 *
345 sin_theta * testf(l);
348 sum += (r * interpolated_dudx(1, 0) - u_theta +
349 interpolated_dudx(0, 1)) *
350 r * sin_theta * dtestfdx(l, 0);
353 sum += (-r * interpolated_p + 2.0 * interpolated_dudx(1, 1) +
355 sin_theta * dtestfdx(l, 1);
358 sum -= ((r * interpolated_dudx(1, 0) - u_theta +
359 interpolated_dudx(0, 1)) *
361 (-r * interpolated_p + 2.0 * u_r +
362 2.0 * u_theta * cot_theta) *
373 double conv = u_r * interpolated_dudx(2, 0) * r * sin_theta;
376 conv += u_theta * interpolated_dudx(2, 1) * sin_theta;
379 conv += u_phi * (u_r * sin_theta + u_theta * cos_theta);
382 sum += (scaled_re_st * r2 * dudt[2] * sin_theta +
383 scaled_re * conv * r) *
386 sum -= r2 * sin_theta * body_force[2] * testf(l);
389 sum += 2.0 * scaled_re_inv_ro *
390 (cos_theta * u_theta + sin_theta * u_r) * r2 *
391 sin_theta * testf(l);
395 sum += (r2 * interpolated_dudx(2, 0) - r * u_phi) *
396 dtestfdx(l, 0) * sin_theta;
400 (interpolated_dudx(2, 1) * sin_theta - u_phi * cos_theta) *
404 sum -= ((r * interpolated_dudx(2, 0) - u_phi) * sin_theta +
405 (interpolated_dudx(2, 1) - u_phi * cot_theta) *
414 residuals[local_eqn] -= sum *
W * hang_weight;
420 unsigned n_master2 = 1;
421 double hang_weight2 = 1.0;
423 for (
unsigned l2 = 0; l2 < n_node; l2++)
429 if (is_node2_hanging)
433 n_master2 = hang_info2_pt->
nmaster();
442 for (
unsigned m2 = 0; m2 < n_master2; m2++)
445 for (
unsigned i2 = 0; i2 < 2 + 1; i2++)
449 if (is_node2_hanging)
453 hang_info2_pt->master_node_pt(m2), u_nodal_index[i2]);
454 hang_weight2 = hang_info2_pt->master_weight(m2);
464 if (local_unknown >= 0)
479 mass_matrix(local_eqn, local_unknown) +=
480 scaled_re_st * psif(l2) * testf(l) * r2 *
481 sin_theta *
W * hang_weight * hang_weight2;
487 r * (psif(l2) * interpolated_dudx(0, 0) +
488 u_r * dpsifdx(l2, 0));
491 jac_conv += u_theta * dpsifdx(l2, 1);
501 scaled_re * jac_conv * r) *
509 2.0 * dpsifdx(l2, 0) * dtestfdx(l, 0) * r2;
513 jac_sum += dpsifdx(l2, 1) * dtestfdx(l, 1);
519 jac_sum += 4.0 * psif[l2] * testf(l);
524 jacobian(local_eqn, local_unknown) -=
525 jac_sum * sin_theta *
W * hang_weight *
539 (interpolated_dudx(0, 1) - 2.0 * u_theta) *
540 psif(l2) * r * sin_theta * testf(l);
545 jac_sum += (r * dpsifdx(l2, 0) - psif(l2)) *
546 dtestfdx(l, 1) * sin_theta;
552 (dpsifdx(l2, 1) * sin_theta +
553 psif(l2) * cos_theta) *
558 jacobian(local_eqn, local_unknown) -=
559 jac_sum *
W * hang_weight * hang_weight2;
569 jacobian(local_eqn, local_unknown) +=
570 2.0 * scaled_re * u_phi * psif[l2] * r *
571 sin_theta * testf[l] *
W * hang_weight *
575 jacobian(local_eqn, local_unknown) +=
576 2.0 * scaled_re_inv_ro * sin_theta *
577 psif(l2) * r2 * sin_theta * testf[l] *
W *
578 hang_weight * hang_weight2;
595 (r2 * interpolated_dudx(1, 0) + r * u_theta) *
596 psif(l2) * sin_theta * testf(l);
600 jac_sum += dpsifdx(l2, 1) * dtestfdx(l, 0) *
607 2.0 * psif(l2) * dtestfdx(l, 1) * sin_theta;
612 jac_sum -= (dpsifdx(l2, 1) * sin_theta -
613 2.0 * psif(l2) * cos_theta) *
617 jacobian(local_eqn, local_unknown) -=
618 jac_sum *
W * hang_weight * hang_weight2;
629 mass_matrix(local_eqn, local_unknown) +=
630 scaled_re_st * psif[l2] * testf[l] *
W *
631 r2 * sin_theta * hang_weight * hang_weight2;
638 r * u_r * dpsifdx(l2, 0) +
639 u_theta * dpsifdx(l2, 1) +
640 (interpolated_dudx(1, 1) + u_r) * psif(l2);
649 scaled_re * r * jac_conv) *
650 testf(l) * sin_theta;
656 jac_sum += (r * dpsifdx(l2, 0) - psif(l2)) *
657 r * dtestfdx(l, 0) * sin_theta;
662 jac_sum += 2.0 * dpsifdx(l2, 1) *
663 dtestfdx(l, 1) * sin_theta;
669 ((r * dpsifdx(l2, 0) - psif(l2)) *
671 2.0 * psif(l2) * cot_theta * cos_theta) *
675 jacobian(local_eqn, local_unknown) -=
676 jac_sum *
W * hang_weight * hang_weight2;
685 jacobian(local_eqn, local_unknown) +=
686 scaled_re * 2.0 * r * psif(l2) * u_phi *
687 cos_theta * testf(l) *
W * hang_weight *
691 jacobian(local_eqn, local_unknown) +=
692 2.0 * scaled_re_inv_ro * cos_theta *
693 psif(l2) * r2 * sin_theta * testf[l] *
W *
694 hang_weight * hang_weight2;
709 jacobian(local_eqn, local_unknown) -=
711 (r * interpolated_dudx(2, 0) + u_phi) *
712 psif(l2) * testf(l) * r * sin_theta *
W *
713 hang_weight * hang_weight2;
716 jacobian(local_eqn, local_unknown) -=
717 2.0 * scaled_re_inv_ro * sin_theta *
718 psif(l2) * r2 * sin_theta * testf[l] *
W *
719 hang_weight * hang_weight2;
727 jacobian(local_eqn, local_unknown) -=
729 (interpolated_dudx(2, 1) * sin_theta +
731 r * psif(l2) * testf(l) *
W * hang_weight *
735 jacobian(local_eqn, local_unknown) -=
736 2.0 * scaled_re_inv_ro * cos_theta *
737 psif(l2) * r2 * sin_theta * testf[l] *
W *
738 hang_weight * hang_weight2;
749 mass_matrix(local_eqn, local_unknown) +=
750 scaled_re_st * psif[l2] * testf[l] *
W *
751 r2 * sin_theta * hang_weight * hang_weight2;
757 r * u_r * dpsifdx(l2, 0) * sin_theta;
761 u_theta * dpsifdx(l2, 1) * sin_theta;
766 (u_r * sin_theta + u_theta * cos_theta) *
774 psif(l2) * r2 * sin_theta +
775 scaled_re * r * jac_conv) *
782 jac_sum += (r * dpsifdx(l2, 0) - psif(l2)) *
783 dtestfdx(l, 0) * r * sin_theta;
788 jac_sum += (dpsifdx(l2, 1) * sin_theta -
789 psif(l2) * cos_theta) *
796 ((r * dpsifdx(l2, 0) - psif(l2)) *
798 (dpsifdx(l2, 1) - psif(l2) * cot_theta) *
803 jacobian(local_eqn, local_unknown) -=
804 jac_sum *
W * hang_weight * hang_weight2;
818 for (
unsigned l2 = 0; l2 < n_pres; l2++)
821 if (pressure_dof_is_hanging[l2])
827 n_master2 = hang_info2_pt->
nmaster();
836 for (
unsigned m2 = 0; m2 < n_master2; m2++)
840 if (pressure_dof_is_hanging[l2])
844 hang_info2_pt->master_node_pt(m2), p_index);
846 hang_weight2 = hang_info2_pt->master_weight(m2);
855 if (local_unknown >= 0)
862 jacobian(local_eqn, local_unknown) +=
864 (r2 * dtestfdx(l, 0) + 2.0 * r * testf[l]) *
W *
865 sin_theta * hang_weight * hang_weight2;
872 jacobian(local_eqn, local_unknown) +=
874 (dtestfdx(l, 1) * sin_theta +
875 cos_theta * testf(l)) *
876 W * hang_weight * hang_weight2;
898 for (
unsigned l = 0; l < n_pres; l++)
901 if (pressure_dof_is_hanging[l])
906 n_master = hang_info_pt->
nmaster();
915 for (
unsigned m = 0; m < n_master; m++)
919 if (pressure_dof_is_hanging[l])
935 residuals[local_eqn] += ((2.0 * u_r + r * interpolated_dudx(0, 0) +
936 interpolated_dudx(1, 1)) *
938 u_theta * cos_theta) *
939 r * testp(l) *
W * hang_weight;
945 unsigned n_master2 = 1;
946 double hang_weight2 = 1.0;
948 for (
unsigned l2 = 0; l2 < n_node; l2++)
954 if (is_node2_hanging)
958 n_master2 = hang_info2_pt->
nmaster();
967 for (
unsigned m2 = 0; m2 < n_master2; m2++)
970 for (
unsigned i2 = 0; i2 < 2 + 1; i2++)
974 if (is_node2_hanging)
978 hang_info2_pt->master_node_pt(m2), u_nodal_index[i2]);
979 hang_weight2 = hang_info2_pt->master_weight(m2);
989 if (local_unknown >= 0)
995 jacobian(local_eqn, local_unknown) +=
996 (2.0 * psif(l2) + r * dpsifdx(l2, 0)) * r *
997 sin_theta * testp(l) *
W * hang_weight *
1005 jacobian(local_eqn, local_unknown) +=
1007 (dpsifdx(l2, 1) * sin_theta +
1008 psif(l2) * cos_theta) *
1009 testp(l) *
W * hang_weight * hang_weight2;
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
double nodal_value(const unsigned &n, const unsigned &i) const
Return the i-th value stored at local node n. Produces suitably interpolated values for hanging nodes...
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
int nodal_local_eqn(const unsigned &n, const unsigned &i) const
Return the local equation number corresponding to the i-th value at the n-th local node.
unsigned nnode() const
Return the number of nodes.
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
double nodal_position(const unsigned &n, const unsigned &i) const
Return the i-th coordinate at local node n. If the node is hanging, the appropriate interpolation is ...
double dnodal_position_dt(const unsigned &n, const unsigned &i) const
Return the i-th component of nodal velocity: dx/dt at local node n.
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.
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.
HangInfo *const & hanging_pt() const
Return pointer to hanging node data (this refers to the geometric hanging node status) (const version...
bool is_hanging() const
Test whether the node is geometrically hanging.
An OomphLibError object which should be thrown when an run-time error is encountered....
int local_hang_eqn(Node *const &node_pt, const unsigned &i)
Access function that returns the local equation number for the hanging node variables (values stored ...
virtual Node * pressure_node_pt(const unsigned &n_p)
Pointer to n_p-th pressure node (Default: NULL, indicating that pressure is not based on nodal interp...
void fill_in_generic_residual_contribution_spherical_nst(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix, unsigned flag)
Add element's contribution to the elemental residual vector and/or Jacobian matrix flag=1: compute bo...
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
virtual double dshape_and_dtest_eulerian_at_knot_spherical_nst(const unsigned &ipt, Shape &psi, DShape &dpsidx, Shape &test, DShape &dtestdx) const =0
Compute the shape functions and derivatives w.r.t. global coords at ipt-th integration point Return J...
virtual void pshape_spherical_nst(const Vector< double > &s, Shape &psi) const =0
Compute the pressure shape functions at local coordinate s.
virtual unsigned u_index_spherical_nst(const unsigned &i) const
Return the index at which the i-th unknown velocity component is stored. The default value,...
const double & re() const
Reynolds number.
const double & re_invro() const
Global Reynolds number multiplied by inverse Rossby number.
virtual double p_spherical_nst(const unsigned &n_p) const =0
Pressure at local pressure "node" n_p Uses suitably interpolated value for hanging nodes.
const double & density_ratio() const
Density ratio for element: Element's density relative to the viscosity used in the definition of the ...
virtual void get_body_force_spherical_nst(const double &time, const unsigned &ipt, const Vector< double > &s, const Vector< double > &x, Vector< double > &result)
Calculate the body force at a given time and local and/or Eulerian position. This function is virtual...
double du_dt_spherical_nst(const unsigned &n, const unsigned &i) const
i-th component of du/dt at local node n. Uses suitably interpolated value for hanging nodes.
virtual int p_nodal_index_spherical_nst() const
Return the index at which the pressure is stored if it is stored at the nodes. If not stored at the n...
const Vector< double > & g() const
Vector of gravitational components.
virtual int p_local_eqn(const unsigned &n) const =0
Access function for the local equation number information for the pressure. p_local_eqn[n] = local eq...
virtual unsigned npres_spherical_nst() const =0
Function to return number of pressure degrees of freedom.
bool ALE_is_disabled
Boolean flag to indicate if ALE formulation is disabled when time-derivatives are computed....
const double & re_st() const
Product of Reynolds and Strouhal number (=Womersley number)
virtual double weight(const unsigned &i, const unsigned &j) const
Access function for j-th weight for the i-th derivative.
Time *const & time_pt() const
Access function for the pointer to time (const version)
double & time()
Return the current value of the continuous time.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...