41 template<
unsigned DIM>
44 Vector<double>& press_mass_diag,
45 Vector<double>& veloc_mass_diag,
46 const unsigned& which_one)
78 Vector<double>
s(
DIM + 1, 0.0);
84 for (
unsigned i = 0;
i <
DIM;
i++)
94 unsigned n_pres = this->npres_nst();
101 int p_index = this->p_nodal_index_nst();
144 for (
unsigned i = 0;
i <
DIM + 1;
i++)
185 for (
unsigned i = 0;
i <
DIM;
i++)
222 this->pshape_nst(
s,
psi_p);
284 template<
unsigned DIM>
287 Vector<double>& residuals,
288 DenseMatrix<double>& jacobian,
289 const unsigned& flag)
291 OomphLibWarning(
"I'm not sure this is correct yet...",
296 if (
ndof() == 0)
return;
302 unsigned n_pres = this->npres_nst();
306 for (
unsigned i = 0;
i <
DIM;
i++)
314 int p_index = this->p_nodal_index_nst();
333 "Pressure advection diffusion does not work in this case\n",
356 Vector<double>
s(
DIM);
360 double scaled_re = this->re() * this->density_ratio();
389 Vector<double> interpolated_u(
DIM, 0.0);
396 for (
unsigned i = 0;
i <
DIM;
i++)
408 for (
unsigned i = 0;
i <
DIM;
i++)
419 if (this->Press_adv_diff_source_fct_pt != 0)
472 for (
unsigned k = 0;
k <
DIM;
k++)
494 this->pressure_node_pt(
l2)->hanging_pt(
p_index);
528 this->Pinned_fp_pressure_eqn) &&
530 this->Pinned_fp_pressure_eqn))
532 for (
unsigned k = 0;
k <
DIM;
k++)
544 this->Pinned_fp_pressure_eqn) &&
546 this->Pinned_fp_pressure_eqn))
562 this->Pressure_advection_diffusion_robin_element_pt.size();
565 this->Pressure_advection_diffusion_robin_element_pt[
e]
566 ->fill_in_generic_residual_contribution_fp_press_adv_diff_robin_bc(
578 template<
unsigned DIM>
581 DenseMatrix<double>& jacobian,
582 DenseMatrix<double>& mass_matrix,
583 const unsigned& flag)
586 if (
ndof() == 0)
return;
592 unsigned n_pres = this->npres_nst();
598 for (
unsigned i = 0;
i <
DIM;
i++)
606 int p_index = this->p_nodal_index_nst();
655 Vector<double>
s(
DIM + 1, 0.0);
661 double scaled_re = this->re() * this->density_ratio();
664 double scaled_re_st = this->re() * this->st() * this->density_ratio();
676 Vector<double>
G = this->g();
694 for (
unsigned i = 0;
i <
DIM + 1;
i++)
704 double J = this->dshape_and_dtest_eulerian_at_knot_nst(
717 double interpolated_p = 0.0;
723 Vector<double> interpolated_u(
DIM, 0.0);
732 DenseMatrix<double> interpolated_dudx(
DIM,
DIM, 0.0);
738 interpolated_p += this->p_nst(
l) *
psip[
l];
751 for (
unsigned i = 0;
i <
DIM;
i++)
766 for (
unsigned j = 0;
j <
DIM;
j++)
778 for (
unsigned l = 0;
l <
n_node;
l++)
781 for (
unsigned i = 0;
i <
DIM;
i++)
790 Vector<double> body_force(
DIM, 0.0);
793 this->get_body_force_nst(
837 for (
unsigned i = 0;
i <
DIM;
i++)
882 for (
unsigned k = 0;
k <
DIM;
k++)
892 for (
unsigned k = 0;
k <
DIM;
k++)
896 (
scaled_re * interpolated_u[
k] * interpolated_dudx(
i,
k) *
901 for (
unsigned k = 0;
k <
DIM;
k++)
908 ((interpolated_dudx(
i,
k) +
909 this->Gamma[
i] * interpolated_dudx(
k,
i)) *
1008 for (
unsigned k = 0;
k <
DIM;
k++)
1020 for (
unsigned k = 0;
k <
DIM;
k++)
1031 for (
unsigned k = 0;
k <
DIM;
k++)
1053 this->pressure_node_pt(
l2)->hanging_pt(
p_index);
1103 if (this->Strouhal_is_stored_as_external_data)
1128 for (
unsigned k = 0;
k <
DIM;
k++)
1133 interpolated_dudx(
i,
k) *
testf[
l] *
W *
1197 for (
unsigned k = 0;
k <
DIM;
k++)
1290 template<
unsigned DIM>
1291 void RefineableSpaceTimeNavierStokesEquations<
1292 DIM>::get_dresidual_dnodal_coordinates(RankThreeTensor<double>&
1293 dresidual_dnodal_coordinates)
1296 throw OomphLibError(
"Space-time update needs to be checked!",
1297 OOMPH_CURRENT_FUNCTION,
1298 OOMPH_EXCEPTION_LOCATION);
1307 const unsigned n_node = nnode();
1310 double time = node_pt(0)->time_stepper_pt()->time_pt()->time();
1313 const unsigned n_pres = this->npres_nst();
1316 unsigned u_nodal_index[DIM];
1317 for (
unsigned i = 0;
i < DIM;
i++)
1319 u_nodal_index[
i] = this->u_index_nst(
i);
1324 const int p_index = this->p_nodal_index_nst();
1328 bool pressure_dof_is_hanging[n_pres];
1334 for (
unsigned l = 0; l < n_pres; ++l)
1336 pressure_dof_is_hanging[l] = pressure_node_pt(l)->is_hanging(p_index);
1342 for (
unsigned l = 0; l < n_pres; ++l)
1344 pressure_dof_is_hanging[l] =
false;
1349 Shape psif(n_node), testf(n_node);
1350 DShape dpsifdx(n_node, DIM), dtestfdx(n_node, DIM);
1353 Shape psip(n_pres), testp(n_pres);
1356 const unsigned n_shape_controlling_node = nshape_controlling_nodes();
1359 RankFourTensor<double> d_dpsifdx_dX(
1360 DIM, n_shape_controlling_node, n_node, DIM);
1361 RankFourTensor<double> d_dtestfdx_dX(
1362 DIM, n_shape_controlling_node, n_node, DIM);
1365 DenseMatrix<double> dJ_dX(DIM, n_shape_controlling_node);
1368 RankFourTensor<double> d_dudx_dX(DIM, n_shape_controlling_node, DIM, DIM);
1373 DenseMatrix<double> d_U_dX(DIM, n_shape_controlling_node, 0.0);
1376 const unsigned n_intpt = integral_pt()->nweight();
1379 Vector<double>
s(DIM);
1383 double scaled_re = this->re() * this->density_ratio();
1384 double scaled_re_st = this->re_st() * this->density_ratio();
1385 double scaled_re_inv_fr = this->re_invfr() * this->density_ratio();
1386 double visc_ratio = this->viscosity_ratio();
1387 Vector<double> G = this->g();
1395 bool element_has_node_with_aux_node_update_fct =
false;
1397 std::map<Node*, unsigned> local_shape_controlling_node_lookup =
1398 shape_controlling_node_lookup();
1401 for (std::map<Node*, unsigned>::iterator it =
1402 local_shape_controlling_node_lookup.begin();
1403 it != local_shape_controlling_node_lookup.end();
1407 Node* nod_pt = it->first;
1410 unsigned q = it->second;
1413 if (nod_pt->has_auxiliary_node_update_fct_pt())
1415 element_has_node_with_aux_node_update_fct =
true;
1418 Vector<double> u_ref(DIM);
1419 for (
unsigned i = 0;
i < DIM;
i++)
1421 u_ref[
i] = *(nod_pt->value_pt(u_nodal_index[
i]));
1425 for (
unsigned p = 0; p < DIM; p++)
1428 double backup = nod_pt->x(p);
1432 nod_pt->x(p) += eps_fd;
1435 nod_pt->perform_auxiliary_node_update_fct();
1439 (*(nod_pt->value_pt(u_nodal_index[p])) - u_ref[p]) / eps_fd;
1442 nod_pt->x(p) = backup;
1445 nod_pt->perform_auxiliary_node_update_fct();
1454 HangInfo* hang_info_pt = 0;
1457 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
1460 for (
unsigned i = 0;
i < DIM;
i++)
1462 s[
i] = integral_pt()->knot(ipt,
i);
1466 const double w = integral_pt()->weight(ipt);
1470 this->dshape_and_dtest_eulerian_at_knot_nst(ipt,
1480 this->pshape_nst(
s, psip, testp);
1484 double interpolated_p = 0.0;
1485 Vector<double> interpolated_u(DIM, 0.0);
1486 Vector<double> interpolated_x(DIM, 0.0);
1487 Vector<double> mesh_velocity(DIM, 0.0);
1488 Vector<double> dudt(DIM, 0.0);
1489 DenseMatrix<double> interpolated_dudx(DIM, DIM, 0.0);
1492 for (
unsigned l = 0; l < n_pres; l++)
1494 interpolated_p += this->p_nst(l) * psip[l];
1500 for (
unsigned l = 0; l < n_node; l++)
1503 for (
unsigned i = 0;
i < DIM;
i++)
1506 const double u_value = nodal_value(l, u_nodal_index[
i]);
1507 interpolated_u[
i] += u_value * psif[l];
1508 interpolated_x[
i] += nodal_position(l,
i) * psif[l];
1509 dudt[
i] += this->du_dt_nst(l,
i) * psif[l];
1512 for (
unsigned j = 0; j < DIM; j++)
1514 interpolated_dudx(
i, j) += u_value * dpsifdx(l, j);
1519 if (!this->ALE_is_disabled)
1522 for (
unsigned l = 0; l < n_node; l++)
1525 for (
unsigned i = 0;
i < DIM;
i++)
1527 mesh_velocity[
i] += this->dnodal_position_dt(l,
i) * psif[l];
1535 for (
unsigned q = 0; q < n_shape_controlling_node; q++)
1538 for (
unsigned p = 0; p < DIM; p++)
1540 for (
unsigned i = 0;
i < DIM;
i++)
1542 for (
unsigned k = 0; k < DIM; k++)
1545 for (
unsigned j = 0; j < n_node; j++)
1548 nodal_value(j, u_nodal_index[
i]) * d_dpsifdx_dX(p, q, j, k);
1550 d_dudx_dX(p, q,
i, k) = aux;
1558 const double pos_time_weight =
1559 node_pt(0)->position_time_stepper_pt()->weight(1, 0);
1560 const double val_time_weight =
1561 node_pt(0)->time_stepper_pt()->weight(1, 0);
1564 Vector<double> body_force(DIM);
1565 this->get_body_force_nst(time, ipt,
s, interpolated_x, body_force);
1568 const double source = this->get_source_nst(time, ipt, interpolated_x);
1571 DenseMatrix<double> d_body_force_dx(DIM, DIM, 0.0);
1572 this->get_body_force_gradient_nst(
1573 time, ipt,
s, interpolated_x, d_body_force_dx);
1576 Vector<double> source_gradient(DIM, 0.0);
1577 this->get_source_gradient_nst(time, ipt, interpolated_x, source_gradient);
1587 unsigned n_master = 1;
1588 double hang_weight = 1.0;
1591 for (
unsigned l = 0; l < n_node; l++)
1594 bool is_node_hanging = node_pt(l)->is_hanging();
1597 if (is_node_hanging)
1599 hang_info_pt = node_pt(l)->hanging_pt();
1602 n_master = hang_info_pt->nmaster();
1611 for (
unsigned m = 0; m < n_master; m++)
1614 for (
unsigned i = 0;
i < DIM;
i++)
1618 if (is_node_hanging)
1621 local_eqn = this->local_hang_eqn(hang_info_pt->master_node_pt(m),
1624 hang_weight = hang_info_pt->master_weight(m);
1630 local_eqn = this->nodal_local_eqn(l, u_nodal_index[
i]);
1640 for (
unsigned p = 0; p < DIM; p++)
1643 for (
unsigned q = 0; q < n_shape_controlling_node; q++)
1649 double sum = body_force[
i] * testf[l];
1652 sum += scaled_re_inv_fr * testf[l] * G[
i];
1655 sum += interpolated_p * dtestfdx(l,
i);
1661 for (
unsigned k = 0; k < DIM; k++)
1664 (interpolated_dudx(
i, k) +
1665 this->Gamma[
i] * interpolated_dudx(k,
i)) *
1672 sum -= scaled_re_st * dudt[
i] * testf[l];
1675 for (
unsigned k = 0; k < DIM; k++)
1677 double tmp = scaled_re * interpolated_u[k];
1678 if (!this->ALE_is_disabled)
1680 tmp -= scaled_re_st * mesh_velocity[k];
1682 sum -= tmp * interpolated_dudx(
i, k) * testf[l];
1687 dresidual_dnodal_coordinates(local_eqn, p, q) +=
1688 sum * dJ_dX(p, q) * w * hang_weight;
1694 sum = d_body_force_dx(
i, p) * psif(q) * testf(l);
1697 sum += interpolated_p * d_dtestfdx_dX(p, q, l,
i);
1700 for (
unsigned k = 0; k < DIM; k++)
1703 visc_ratio * ((interpolated_dudx(
i, k) +
1704 this->Gamma[
i] * interpolated_dudx(k,
i)) *
1705 d_dtestfdx_dX(p, q, l, k) +
1706 (d_dudx_dX(p, q,
i, k) +
1707 this->Gamma[
i] * d_dudx_dX(p, q, k,
i)) *
1712 for (
unsigned k = 0; k < DIM; k++)
1714 double tmp = scaled_re * interpolated_u[k];
1715 if (!this->ALE_is_disabled)
1717 tmp -= scaled_re_st * mesh_velocity[k];
1719 sum -= tmp * d_dudx_dX(p, q,
i, k) * testf(l);
1721 if (!this->ALE_is_disabled)
1723 sum += scaled_re_st * pos_time_weight * psif(q) *
1724 interpolated_dudx(
i, p) * testf(l);
1728 dresidual_dnodal_coordinates(local_eqn, p, q) +=
1729 sum * J * w * hang_weight;
1737 if (element_has_node_with_aux_node_update_fct)
1740 for (
unsigned q_local = 0; q_local < n_node; q_local++)
1744 unsigned n_master2 = 1;
1745 double hang_weight2 = 1.0;
1746 HangInfo* hang_info2_pt = 0;
1749 bool is_node_hanging2 = node_pt(q_local)->is_hanging();
1751 Node* actual_shape_controlling_node_pt = node_pt(q_local);
1754 if (is_node_hanging2)
1756 hang_info2_pt = node_pt(q_local)->hanging_pt();
1759 n_master2 = hang_info2_pt->nmaster();
1768 for (
unsigned mm = 0; mm < n_master2; mm++)
1770 if (is_node_hanging2)
1772 actual_shape_controlling_node_pt =
1773 hang_info2_pt->master_node_pt(mm);
1774 hang_weight2 = hang_info2_pt->master_weight(mm);
1778 unsigned q = local_shape_controlling_node_lookup
1779 [actual_shape_controlling_node_pt];
1782 for (
unsigned p = 0; p < DIM; p++)
1784 double sum = -visc_ratio * this->Gamma[
i] *
1785 dpsifdx(q_local,
i) * dtestfdx(l, p) -
1786 scaled_re * psif(q_local) *
1787 interpolated_dudx(
i, p) * testf(l);
1790 sum -= scaled_re_st * val_time_weight * psif(q_local) *
1792 for (
unsigned k = 0; k < DIM; k++)
1795 visc_ratio * dpsifdx(q_local, k) * dtestfdx(l, k);
1796 double tmp = scaled_re * interpolated_u[k];
1797 if (!this->ALE_is_disabled)
1799 tmp -= scaled_re_st * mesh_velocity[k];
1801 sum -= tmp * dpsifdx(q_local, k) * testf(l);
1805 dresidual_dnodal_coordinates(local_eqn, p, q) +=
1806 sum * d_U_dX(p, q) * J * w * hang_weight * hang_weight2;
1823 for (
unsigned l = 0; l < n_pres; l++)
1826 if (pressure_dof_is_hanging[l])
1830 hang_info_pt = this->pressure_node_pt(l)->hanging_pt(p_index);
1833 n_master = hang_info_pt->nmaster();
1842 for (
unsigned m = 0; m < n_master; m++)
1846 if (pressure_dof_is_hanging[l])
1850 this->local_hang_eqn(hang_info_pt->master_node_pt(m), p_index);
1852 hang_weight = hang_info_pt->master_weight(m);
1856 local_eqn = this->p_local_eqn(l);
1864 for (
unsigned p = 0; p < DIM; p++)
1867 for (
unsigned q = 0; q < n_shape_controlling_node; q++)
1873 double aux = -source;
1876 for (
unsigned k = 0; k < DIM; k++)
1878 aux += interpolated_dudx(k, k);
1882 dresidual_dnodal_coordinates(local_eqn, p, q) +=
1883 aux * dJ_dX(p, q) * testp[l] * w * hang_weight;
1890 aux = -source_gradient[p] * psif(q);
1891 for (
unsigned k = 0; k < DIM; k++)
1893 aux += d_dudx_dX(p, q, k, k);
1896 dresidual_dnodal_coordinates(local_eqn, p, q) +=
1897 aux * testp[l] * J * w * hang_weight;
1904 if (element_has_node_with_aux_node_update_fct)
1907 for (
unsigned q_local = 0; q_local < n_node; q_local++)
1911 unsigned n_master2 = 1;
1912 double hang_weight2 = 1.0;
1913 HangInfo* hang_info2_pt = 0;
1916 bool is_node_hanging2 = node_pt(q_local)->is_hanging();
1918 Node* actual_shape_controlling_node_pt = node_pt(q_local);
1921 if (is_node_hanging2)
1923 hang_info2_pt = node_pt(q_local)->hanging_pt();
1926 n_master2 = hang_info2_pt->nmaster();
1935 for (
unsigned mm = 0; mm < n_master2; mm++)
1937 if (is_node_hanging2)
1939 actual_shape_controlling_node_pt =
1940 hang_info2_pt->master_node_pt(mm);
1941 hang_weight2 = hang_info2_pt->master_weight(mm);
1945 unsigned q = local_shape_controlling_node_lookup
1946 [actual_shape_controlling_node_pt];
1949 for (
unsigned p = 0; p < DIM; p++)
1951 double aux = dpsifdx(q_local, p) * testp(l);
1952 dresidual_dnodal_coordinates(local_eqn, p, q) +=
1953 aux * d_U_dX(p, q) * J * w * hang_weight * hang_weight2;
1969 template class RefineableSpaceTimeNavierStokesEquations<2>;
1970 template class RefineableQTaylorHoodSpaceTimeElement<2>;
bool ALE_is_disabled
Boolean flag to indicate if ALE formulation is disabled when time-derivatives are computed....
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
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 dshape_eulerian_at_knot(const unsigned &ipt, Shape &psi, DShape &dpsidx) const
Return the geometric shape functions and also first derivatives w.r.t. global coordinates at the ipt-...
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.
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 ...
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
virtual double J_eulerian_at_knot(const unsigned &ipt) const
Return the Jacobian of the mapping from local to global coordinates at the ipt-th integration point.
virtual void shape_at_knot(const unsigned &ipt, Shape &psi) const
Return the geometric shape function at the ipt-th integration point.
static double Default_fd_jacobian_step
Double used for the default finite difference step in elemental jacobian calculations.
unsigned ndof() const
Return the number of equations/dofs in the element.
unsigned long eqn_number(const unsigned &ieqn_local) const
Return the global equation number corresponding to the ieqn_local-th local equation number.
int external_local_eqn(const unsigned &i, const unsigned &j)
Return the local equation number corresponding to the j-th value stored at the i-th external data.
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.
bool is_hanging() const
Test whether the node is geometrically hanging.
HangInfo *const & hanging_pt() const
Return pointer to hanging node data (this refers to the geometric hanging node status) (const version...
void get_pressure_and_velocity_mass_matrix_diagonal(Vector< double > &press_mass_diag, Vector< double > &veloc_mass_diag, const unsigned &which_one=0)
Compute the diagonal of the velocity/pressure mass matrices. If which one=0, both are computed,...
void fill_in_generic_pressure_advection_diffusion_contribution_nst(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &compute_jacobian_flag)
Compute the residuals for the associated pressure advection diffusion problem. Used by the Fp precond...
void fill_in_generic_residual_contribution_nst(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix, const unsigned &compute_jacobian_flag)
Add the elements contribution to elemental residual vector and/or Jacobian matrix....
TAdvectionDiffusionReactionElement()
Constructor: Call constructors for TElement and AdvectionDiffusionReaction equations.
//////////////////////////////////////////////////////////////////// ////////////////////////////////...