50 template<
unsigned DIM>
58 template<
unsigned DIM>
62 template<
unsigned DIM>
66 template<
unsigned DIM>
70 template<
unsigned DIM>
82 template<
unsigned DIM>
86 const unsigned& which_one)
89 unsigned n_dof=ndof();
91 if ((which_one==0)||(which_one==1)) press_mass_diag.assign(n_dof,0.0);
92 if ((which_one==0)||(which_one==2)) veloc_mass_diag.assign(n_dof,0.0);
95 unsigned n_node = nnode();
98 unsigned n_dim = this->dim();
105 for(
unsigned i=0;
i<n_dim;
i++)
107 u_nodal_index[
i] = this->u_index_nst(
i);
114 unsigned n_pres = npres_nst();
120 unsigned n_intpt = integral_pt()->nweight();
126 for(
unsigned ipt=0; ipt<n_intpt; ipt++)
130 double w = integral_pt()->weight(ipt);
133 double J = J_eulerian_at_knot(ipt);
136 for(
unsigned i=0;
i<n_dim;
i++)
138 s[
i] = integral_pt()->knot(ipt,
i);
147 if ((which_one==0)||(which_one==2))
151 shape_at_knot(ipt,psi);
154 for(
unsigned l=0; l<n_node; l++)
157 for(
unsigned i=0;
i<n_dim;
i++)
159 local_eqn = nodal_local_eqn(l,u_nodal_index[
i]);
165 veloc_mass_diag[local_eqn] += pow(psi[l],2) *
W;
172 if ((which_one==0)||(which_one==1))
178 for(
unsigned l=0; l<n_pres; l++)
181 local_eqn = p_local_eqn(l);
187 press_mass_diag[local_eqn] += pow(psi_p[l],2) *
W;
200 template <
unsigned DIM>
214 unsigned n_node = this->nnode();
219 unsigned n_intpt = this->integral_pt()->nweight();
222 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
226 for(
unsigned i=0;
i<DIM;
i++)
228 s[
i] = this->integral_pt()->knot(ipt,
i);
232 double w = this->integral_pt()->weight(ipt);
235 double J=this->J_eulerian(s);
240 for (
unsigned i=0;
i<DIM;
i++)
243 u=this->interpolated_u_nst(s,
i);
259 template<
unsigned DIM>
264 double& error,
double& norm)
276 unsigned n_intpt = integral_pt()->nweight();
278 outfile <<
"ZONE" << std::endl;
284 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
288 for(
unsigned i=0;
i<DIM;
i++)
290 s[
i] = integral_pt()->knot(ipt,
i);
294 double w = integral_pt()->weight(ipt);
297 double J=J_eulerian(s);
306 (*exact_soln_pt)(time,x,exact_soln);
309 for(
unsigned i=0;
i<DIM;
i++)
311 norm+=exact_soln[
i]*exact_soln[
i]*
W;
312 error+=(exact_soln[
i]-interpolated_u_nst(s,
i))*
313 (exact_soln[
i]-interpolated_u_nst(s,
i))*W;
317 for(
unsigned i=0;
i<DIM;
i++)
319 outfile << x[
i] <<
" ";
323 for(
unsigned i=0;
i<DIM;
i++)
325 outfile << exact_soln[
i]-interpolated_u_nst(s,
i) <<
" ";
328 outfile << std::endl;
339 template<
unsigned DIM>
341 std::ostream &outfile,
343 double& error,
double& norm)
356 unsigned n_intpt = integral_pt()->nweight();
359 outfile <<
"ZONE" << std::endl;
365 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
369 for(
unsigned i=0;
i<DIM;
i++)
371 s[
i] = integral_pt()->knot(ipt,
i);
375 double w = integral_pt()->weight(ipt);
378 double J=J_eulerian(s);
387 (*exact_soln_pt)(x,exact_soln);
390 for(
unsigned i=0;
i<DIM;
i++)
392 norm+=exact_soln[
i]*exact_soln[
i]*
W;
393 error+=(exact_soln[
i]-interpolated_u_nst(s,
i))*
394 (exact_soln[
i]-interpolated_u_nst(s,
i))*W;
398 for(
unsigned i=0;
i<DIM;
i++)
400 outfile << x[
i] <<
" ";
404 for(
unsigned i=0;
i<DIM;
i++)
406 outfile << exact_soln[
i]-interpolated_u_nst(s,
i) <<
" ";
408 outfile << std::endl;
418 template<
unsigned DIM>
420 const unsigned &nplot,
431 outfile << tecplot_zone_string(nplot);
437 unsigned num_plot_points=nplot_points(nplot);
438 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
442 get_s_plot(iplot,nplot,s);
448 (*exact_soln_pt)(x,exact_soln);
451 for(
unsigned i=0;
i<DIM;
i++)
453 outfile << x[
i] <<
" ";
457 for(
unsigned i=0;
i<exact_soln.size();
i++)
459 outfile << exact_soln[
i] <<
" ";
462 outfile << std::endl;
467 write_tecplot_zone_footer(outfile,nplot);
477 template<
unsigned DIM>
479 const unsigned &nplot,
491 outfile << tecplot_zone_string(nplot);
497 unsigned num_plot_points=nplot_points(nplot);
498 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
502 get_s_plot(iplot,nplot,s);
508 (*exact_soln_pt)(time,x,exact_soln);
511 for(
unsigned i=0;
i<DIM;
i++)
513 outfile << x[
i] <<
" ";
517 for(
unsigned i=0;
i<exact_soln.size();
i++)
519 outfile << exact_soln[
i] <<
" ";
522 outfile << std::endl;
526 write_tecplot_zone_footer(outfile,nplot);
537 template<
unsigned DIM>
539 const unsigned& nplot,
544 unsigned n_node = nnode();
555 outfile << tecplot_zone_string(nplot);
558 unsigned num_plot_points=nplot_points(nplot);
559 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
563 get_s_plot(iplot,nplot,s);
569 for(
unsigned i=0;
i<DIM;
i++)
571 interpolated_x[
i]=0.0;
572 interpolated_u[
i]=0.0;
574 unsigned u_nodal_index = u_index_nst(
i);
576 for(
unsigned l=0;l<n_node;l++)
578 interpolated_u[
i] += nodal_value(t,l,u_nodal_index)*psi[l];
579 interpolated_x[
i] += nodal_position(t,l,
i)*psi[l];
584 for(
unsigned i=0;
i<DIM;
i++)
586 outfile << interpolated_x[
i] <<
" ";
590 for(
unsigned i=0;
i<DIM;
i++)
592 outfile << interpolated_u[
i] <<
" ";
595 outfile << std::endl;
599 write_tecplot_zone_footer(outfile,nplot);
609 template<
unsigned DIM>
611 const unsigned &nplot)
618 outfile << tecplot_zone_string(nplot);
621 unsigned num_plot_points=nplot_points(nplot);
622 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
626 get_s_plot(iplot,nplot,s);
629 for(
unsigned i=0;
i<DIM;
i++)
631 outfile << interpolated_x(s,
i) <<
" ";
635 for(
unsigned i=0;
i<DIM;
i++)
637 outfile << interpolated_u_nst(s,
i) <<
" ";
641 outfile << interpolated_p_nst(s) <<
" ";
643 outfile << std::endl;
645 outfile << std::endl;
648 write_tecplot_zone_footer(outfile,nplot);
659 template<
unsigned DIM>
661 const unsigned &nplot)
668 fprintf(file_pt,
"%s",tecplot_zone_string(nplot).c_str());
671 unsigned num_plot_points=nplot_points(nplot);
672 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
676 get_s_plot(iplot,nplot,s);
679 for(
unsigned i=0;
i<DIM;
i++)
681 fprintf(file_pt,
"%g ",interpolated_x(s,
i));
685 for(
unsigned i=0;
i<DIM;
i++)
687 fprintf(file_pt,
"%g ",interpolated_u_nst(s,
i));
691 fprintf(file_pt,
"%g \n",interpolated_p_nst(s));
693 fprintf(file_pt,
"\n");
696 write_tecplot_zone_footer(file_pt,nplot);
707 template<
unsigned DIM>
709 const unsigned &nplot)
722 outfile << tecplot_zone_string(nplot);
725 unsigned n_node = nnode();
729 DShape dpsifdx(n_node,DIM);
732 unsigned num_plot_points=nplot_points(nplot);
733 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
737 get_s_plot(iplot,nplot,s);
740 dshape_eulerian(s,psif,dpsifdx);
749 for(
unsigned i=0;
i<DIM;
i++)
754 for(
unsigned j=0;j<DIM;j++)
756 interpolated_dudx(
i,j) = 0.0;
764 for(
unsigned i=0;
i<DIM;
i++)
767 unsigned u_nodal_index = u_index_nst(
i);
769 for(
unsigned l=0;l<n_node;l++)
771 dudt[
i]+=du_dt_nst(l,u_nodal_index)*psif[l];
772 mesh_veloc[
i]+=dnodal_position_dt(l,
i)*psif[l];
775 for(
unsigned j=0;j<DIM;j++)
777 interpolated_dudx(
i,j) += nodal_value(l,u_nodal_index)*dpsifdx(l,j);
784 for(
unsigned i=0;
i<DIM;
i++)
787 for (
unsigned k=0;k<DIM;k++)
789 dudt_ALE[
i]-=mesh_veloc[k]*interpolated_dudx(
i,k);
795 for(
unsigned i=0;
i<DIM;
i++)
797 outfile << interpolated_x(s,
i) <<
" ";
801 for(
unsigned i=0;
i<DIM;
i++)
803 outfile << interpolated_u_nst(s,
i) <<
" ";
807 outfile << interpolated_p_nst(s) <<
" ";
810 for(
unsigned i=0;
i<DIM;
i++)
812 outfile << dudt_ALE[
i] <<
" ";
822 outfile << dissipation(s) <<
" ";
825 outfile << std::endl;
830 write_tecplot_zone_footer(outfile,nplot);
840 template<
unsigned DIM>
842 const unsigned &nplot)
861 "Can't output vorticity in 1D - in fact, what do you mean\n";
862 error_message +=
"by the 1D Navier-Stokes equations?\n";
865 OOMPH_CURRENT_FUNCTION,
866 OOMPH_EXCEPTION_LOCATION);
870 outfile << tecplot_zone_string(nplot);
873 unsigned num_plot_points=nplot_points(nplot);
874 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
878 get_s_plot(iplot,nplot,s);
881 for(
unsigned i=0;
i<DIM;
i++)
883 outfile << interpolated_x(s,
i) <<
" ";
887 get_vorticity(s,vorticity);
891 outfile << vorticity[0];
895 outfile << vorticity[0] <<
" " 896 << vorticity[1] <<
" " 897 << vorticity[2] <<
" ";
900 outfile << std::endl;
902 outfile << std::endl;
905 write_tecplot_zone_footer(outfile,nplot);
914 template<
unsigned DIM>
922 unsigned n_intpt = integral_pt()->nweight();
928 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
932 for(
unsigned i=0;
i<DIM;
i++)
934 s[
i] = integral_pt()->knot(ipt,
i);
938 double w = integral_pt()->weight(ipt);
941 double J = J_eulerian(s);
945 strain_rate(s,strainrate);
948 double local_diss=0.0;
949 for(
unsigned i=0;
i<DIM;
i++)
951 for(
unsigned j=0;j<DIM;j++)
953 local_diss+=2.0*strainrate(
i,j)*strainrate(
i,j);
957 diss+=local_diss*w*J;
969 template<
unsigned DIM>
977 strain_rate(s,strainrate);
980 double press=interpolated_p_nst(s);
983 for (
unsigned i=0;
i<DIM;
i++)
985 traction[
i]=-press*N[
i];
986 for (
unsigned j=0;j<DIM;j++)
988 traction[
i]+=2.0*strainrate(
i,j)*N[j];
1000 template<
unsigned DIM>
1011 strain_rate(s,strainrate);
1014 double press=interpolated_p_nst(s);
1017 for (
unsigned i=0;
i<DIM;
i++)
1020 traction_p[
i]=-press*N[
i];
1021 for (
unsigned j=0;j<DIM;j++)
1024 traction_visc[
i]+=2.0*strainrate(
i,j)*N[j];
1027 traction_visc_n[
i]=traction_visc[
i]*N[
i];
1028 traction_visc_t[
i]=traction_visc[
i]-traction_visc_n[
i];
1036 template<
unsigned DIM>
1041 strain_rate(s,strainrate);
1044 double local_diss=0.0;
1045 for(
unsigned i=0;
i<DIM;
i++)
1047 for(
unsigned j=0;j<DIM;j++)
1049 local_diss+=2.0*strainrate(
i,j)*strainrate(
i,j);
1059 template<
unsigned DIM>
1065 if ((strainrate.
ncol()!=DIM)||(strainrate.
nrow()!=DIM))
1067 std::ostringstream error_message;
1068 error_message <<
"The strain rate has incorrect dimensions " 1069 << strainrate.
ncol() <<
" x " 1070 << strainrate.
nrow() <<
" Not " << DIM << std::endl;
1073 OOMPH_CURRENT_FUNCTION,
1074 OOMPH_EXCEPTION_LOCATION);
1082 unsigned n_node = nnode();
1086 DShape dpsidx(n_node,DIM);
1089 dshape_eulerian(s,psi,dpsidx);
1092 for(
unsigned i=0;
i<DIM;
i++)
1094 for(
unsigned j=0;j<DIM;j++)
1101 for(
unsigned i=0;
i<DIM;
i++)
1104 unsigned u_nodal_index = u_index_nst(
i);
1106 for(
unsigned j=0;j<DIM;j++)
1109 for(
unsigned l=0;l<n_node;l++)
1111 dudx(
i,j) += nodal_value(l,u_nodal_index)*dpsidx(l,j);
1117 for(
unsigned i=0;
i<DIM;
i++)
1120 for(
unsigned j=0;j<DIM;j++)
1122 strainrate(
i,j)=0.5*(dudx(
i,j)+dudx(j,
i));
1140 if (vorticity.size()!=1)
1142 std::ostringstream error_message;
1144 <<
"Computation of vorticity in 2D requires a 1D vector\n" 1145 <<
"which contains the only non-zero component of the\n" 1146 <<
"vorticity vector. You've passed a vector of size " 1147 << vorticity.size() << std::endl;
1150 OOMPH_CURRENT_FUNCTION,
1151 OOMPH_EXCEPTION_LOCATION);
1162 unsigned n_node = nnode();
1166 DShape dpsidx(n_node,DIM);
1169 dshape_eulerian(s,psi,dpsidx);
1172 for(
unsigned i=0;
i<DIM;
i++)
1174 for(
unsigned j=0;j<DIM;j++)
1181 for(
unsigned i=0;
i<DIM;
i++)
1184 unsigned u_nodal_index = u_index_nst(
i);
1186 for(
unsigned j=0;j<DIM;j++)
1189 for(
unsigned l=0;l<n_node;l++)
1191 dudx(
i,j) += nodal_value(l,u_nodal_index)*dpsidx(l,j);
1197 vorticity[0]=dudx(1,0)-dudx(0,1);
1213 if (vorticity.size()!=3)
1215 std::ostringstream error_message;
1217 <<
"Computation of vorticity in 3D requires a 3D vector\n" 1218 <<
"which contains the only non-zero component of the\n" 1219 <<
"vorticity vector. You've passed a vector of size " 1220 << vorticity.size() << std::endl;
1223 OOMPH_CURRENT_FUNCTION,
1224 OOMPH_EXCEPTION_LOCATION);
1235 unsigned n_node = nnode();
1239 DShape dpsidx(n_node,DIM);
1242 dshape_eulerian(s,psi,dpsidx);
1245 for(
unsigned i=0;
i<DIM;
i++)
1247 for(
unsigned j=0;j<DIM;j++)
1254 for(
unsigned i=0;
i<DIM;
i++)
1257 unsigned u_nodal_index = u_index_nst(
i);
1259 for(
unsigned j=0;j<DIM;j++)
1262 for(
unsigned l=0;l<n_node;l++)
1264 dudx(
i,j) += nodal_value(l,u_nodal_index)*dpsidx(l,j);
1269 vorticity[0]=dudx(2,1)-dudx(1,2);
1270 vorticity[1]=dudx(0,2)-dudx(2,0);
1271 vorticity[2]=dudx(1,0)-dudx(0,1);
1284 template<
unsigned DIM>
1292 unsigned n_intpt = integral_pt()->nweight();
1298 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
1301 for(
unsigned i=0;
i<DIM;
i++)
1303 s[
i] = integral_pt()->knot(ipt,
i);
1307 double w = integral_pt()->weight(ipt);
1310 double J = J_eulerian(s);
1313 double veloc_squared=0.0;
1314 for(
unsigned i=0;
i<DIM;
i++)
1316 veloc_squared+=interpolated_u_nst(s,
i)*interpolated_u_nst(s,
i);
1319 kin_en+=0.5*veloc_squared*w*J;
1330 template<
unsigned DIM>
1334 double d_kin_en_dt=0.0;
1337 const unsigned n_intpt = integral_pt()->nweight();
1343 const unsigned n_node = this->nnode();
1347 DShape dpsidx(n_node,DIM);
1350 unsigned u_index[DIM];
1351 for(
unsigned i=0;
i<DIM;
i++) {u_index[
i] = this->u_index_nst(
i);}
1354 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
1357 double J = dshape_eulerian_at_knot(ipt,psi,dpsidx);
1360 double w = integral_pt()->weight(ipt);
1363 Vector<double> interpolated_u(DIM,0.0), interpolated_dudt(DIM,0.0);
1366 for(
unsigned l=0;l<n_node;l++)
1369 for(
unsigned i=0;
i<DIM;
i++)
1371 interpolated_u[
i] += nodal_value(l,u_index[
i])*psi(l);
1372 interpolated_dudt[
i] += du_dt_nst(l,u_index[i])*psi(l);
1383 for(
unsigned l=0;l<n_node;l++)
1385 for(
unsigned i=0;
i<DIM;
i++)
1387 mesh_velocity[
i] += this->dnodal_position_dt(l,
i)*psi(l);
1389 for(
unsigned j=0;j<DIM;j++)
1391 interpolated_dudx(
i,j) +=
1392 this->nodal_value(l,u_index[
i])*dpsidx(l,j);
1398 for(
unsigned i=0;
i<DIM;
i++)
1400 for (
unsigned k=0;k<DIM;k++)
1402 interpolated_dudt[
i] -= mesh_velocity[k]*interpolated_dudx(
i,k);
1410 for(
unsigned i=0;
i<DIM;
i++)
1411 { sum += interpolated_u[
i]*interpolated_dudt[
i];}
1413 d_kin_en_dt += sum*w*J;
1424 template<
unsigned DIM>
1432 unsigned n_intpt = integral_pt()->nweight();
1438 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
1442 for(
unsigned i=0;
i<DIM;
i++)
1444 s[
i] = integral_pt()->knot(ipt,
i);
1448 double w = integral_pt()->weight(ipt);
1451 double J = J_eulerian(s);
1457 double press=interpolated_p_nst(s);
1474 template<
unsigned DIM>
1482 if (ndof()==0)
return;
1485 unsigned n_node = nnode();
1488 unsigned n_pres = npres_nst();
1491 unsigned u_nodal_index[DIM];
1492 for(
unsigned i=0;
i<DIM;
i++) {u_nodal_index[
i] = u_index_nst(
i);}
1496 DShape dpsidx(n_node,DIM);
1499 Shape psip(n_pres), testp(n_pres);
1500 DShape dpsip(n_pres,DIM);
1501 DShape dtestp(n_pres,DIM);
1504 unsigned n_intpt = integral_pt()->nweight();
1511 double scaled_re = re()*density_ratio();
1514 int local_eqn=0, local_unknown=0;
1517 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
1520 for(
unsigned i=0;
i<DIM;
i++) s[
i] = integral_pt()->knot(ipt,
i);
1523 double w = integral_pt()->weight(ipt);
1527 double J = this->dshape_eulerian_at_knot(ipt,psif,dpsidx);
1530 this->dpshape_and_dptest_eulerian_nst(s,psip,dpsip,testp,dtestp);
1542 for(
unsigned l=0;l<n_pres;l++)
1544 for (
unsigned i=0;
i<DIM;
i++)
1546 interpolated_dpdx[
i] += p_nst(l)*dpsip(l,
i);
1553 for(
unsigned l=0;l<n_node;l++)
1556 for(
unsigned i=0;
i<DIM;
i++)
1559 double u_value = raw_nodal_value(l,u_nodal_index[
i]);
1560 interpolated_u[
i] += u_value*psif[l];
1561 interpolated_x[
i] += raw_nodal_position(l,i)*psif[l];
1567 if (Press_adv_diff_source_fct_pt!=0)
1569 source=Press_adv_diff_source_fct_pt(interpolated_x);
1573 for(
unsigned l=0;l<n_pres;l++)
1575 local_eqn = p_local_eqn(l);
1580 residuals[local_eqn] -= source*testp[l]*
W;
1581 for(
unsigned k=0;k<DIM;k++)
1583 residuals[local_eqn] += interpolated_dpdx[k]*
1584 (scaled_re*interpolated_u[k]*testp[l]+dtestp(l,k))*W;
1591 for(
unsigned l2=0;l2<n_pres;l2++)
1593 local_unknown = p_local_eqn(l2);
1596 if(local_unknown >= 0)
1598 if ((
int(eqn_number(local_eqn))!=Pinned_fp_pressure_eqn)&&
1599 (
int(eqn_number(local_unknown))!=Pinned_fp_pressure_eqn))
1601 for(
unsigned k=0;k<DIM;k++)
1603 jacobian(local_eqn,local_unknown)+=dtestp(l2,k)*
1604 (scaled_re*interpolated_u[k]*testp[l]+dtestp(l,k))*W;
1609 if ((
int(eqn_number(local_eqn))==Pinned_fp_pressure_eqn)&&
1610 (int(eqn_number(local_unknown))==Pinned_fp_pressure_eqn))
1612 jacobian(local_eqn,local_unknown)=1.0;
1623 unsigned nrobin=Pressure_advection_diffusion_robin_element_pt.size();
1624 for (
unsigned e=0;
e<nrobin;
e++)
1626 Pressure_advection_diffusion_robin_element_pt[
e]->
1627 fill_in_generic_residual_contribution_fp_press_adv_diff_robin_bc(
1628 residuals,jacobian,flag);
1638 template<
unsigned DIM>
1646 if (ndof()==0)
return;
1649 unsigned n_node = nnode();
1652 double time=node_pt(0)->time_stepper_pt()->time_pt()->time();
1655 unsigned n_pres = npres_nst();
1658 unsigned u_nodal_index[DIM];
1659 for(
unsigned i=0;
i<DIM;
i++) {u_nodal_index[
i] = u_index_nst(
i);}
1662 Shape psif(n_node), testf(n_node);
1663 DShape dpsifdx(n_node,DIM), dtestfdx(n_node,DIM);
1666 Shape psip(n_pres), testp(n_pres);
1669 unsigned n_intpt = integral_pt()->nweight();
1676 double scaled_re = re()*density_ratio();
1677 double scaled_re_st = re_st()*density_ratio();
1678 double scaled_re_inv_fr = re_invfr()*density_ratio();
1679 double visc_ratio = viscosity_ratio();
1683 int local_eqn=0, local_unknown=0;
1686 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
1689 for(
unsigned i=0;
i<DIM;
i++) s[
i] = integral_pt()->knot(ipt,
i);
1691 double w = integral_pt()->weight(ipt);
1695 dshape_and_dtest_eulerian_at_knot_nst(ipt,psif,dpsifdx,testf,dtestfdx);
1698 pshape_nst(s,psip,testp);
1705 double interpolated_p=0.0;
1713 for(
unsigned l=0;l<n_pres;l++) interpolated_p += p_nst(l)*psip[l];
1718 for(
unsigned l=0;l<n_node;l++)
1721 for(
unsigned i=0;
i<DIM;
i++)
1724 double u_value = raw_nodal_value(l,u_nodal_index[
i]);
1725 interpolated_u[
i] += u_value*psif[l];
1726 interpolated_x[
i] += raw_nodal_position(l,i)*psif[l];
1727 dudt[
i] += du_dt_nst(l,i)*psif[l];
1730 for(
unsigned j=0;j<DIM;j++)
1732 interpolated_dudx(i,j) += u_value*dpsifdx(l,j);
1740 for(
unsigned l=0;l<n_node;l++)
1743 for(
unsigned i=0;
i<DIM;
i++)
1745 mesh_velocity[
i] += this->raw_dnodal_position_dt(l,
i)*psif[l];
1752 get_body_force_nst(time,ipt,s,interpolated_x,body_force);
1755 double source = get_source_nst(time,ipt,interpolated_x);
1762 for(
unsigned l=0;l<n_node;l++)
1765 for(
unsigned i=0;
i<DIM;
i++)
1768 local_eqn = nodal_local_eqn(l,u_nodal_index[
i]);
1772 residuals[local_eqn] +=
1773 body_force[
i]*testf[l]*
W;
1776 residuals[local_eqn] += scaled_re_inv_fr*testf[l]*G[
i]*
W;
1779 residuals[local_eqn] += interpolated_p*dtestfdx(l,i)*
W;
1785 for(
unsigned k=0;k<DIM;k++)
1787 residuals[local_eqn] -= visc_ratio*
1788 (interpolated_dudx(i,k) + Gamma[
i]*interpolated_dudx(k,i))
1794 residuals[local_eqn] -= scaled_re_st*dudt[
i]*testf[l]*
W;
1798 for(
unsigned k=0;k<DIM;k++)
1800 double tmp=scaled_re*interpolated_u[k];
1802 residuals[local_eqn] -= tmp*interpolated_dudx(i,k)*testf[l]*
W;
1810 for(
unsigned l2=0;l2<n_node;l2++)
1813 for(
unsigned i2=0;i2<DIM;i2++)
1816 local_unknown = nodal_local_eqn(l2,u_nodal_index[i2]);
1817 if(local_unknown >= 0)
1820 jacobian(local_eqn,local_unknown)
1821 -= visc_ratio*Gamma[
i]*dpsifdx(l2,i)*dtestfdx(l,i2)*
W;
1827 for(
unsigned k=0;k<DIM;k++)
1829 jacobian(local_eqn,local_unknown)
1830 -= visc_ratio*dpsifdx(l2,k)*dtestfdx(l,k)*
W;
1835 jacobian(local_eqn,local_unknown)
1836 -= scaled_re*psif[l2]*interpolated_dudx(i,i2)*testf[l]*
W;
1847 mass_matrix(local_eqn,local_unknown) +=
1848 scaled_re_st*psif[l2]*testf[l]*
W;
1852 jacobian(local_eqn,local_unknown)
1854 node_pt(l2)->time_stepper_pt()->weight(1,0)*
1855 psif[l2]*testf[l]*
W;
1858 for(
unsigned k=0;k<DIM;k++)
1860 double tmp=scaled_re*interpolated_u[k];
1862 jacobian(local_eqn,local_unknown) -=
1863 tmp*dpsifdx(l2,k)*testf[l]*
W;
1873 for(
unsigned l2=0;l2<n_pres;l2++)
1876 local_unknown = p_local_eqn(l2);
1877 if(local_unknown >= 0)
1879 jacobian(local_eqn,local_unknown)
1880 += psip[l2]*dtestfdx(l,i)*
W;
1896 for(
unsigned l=0;l<n_pres;l++)
1898 local_eqn = p_local_eqn(l);
1908 for(
unsigned k=0;k<DIM;k++)
1911 aux += interpolated_dudx(k,k);
1914 residuals[local_eqn]+=aux*testp[l]*
W;
1920 for(
unsigned l2=0;l2<n_node;l2++)
1923 for(
unsigned i2=0;i2<DIM;i2++)
1926 local_unknown = nodal_local_eqn(l2,u_nodal_index[i2]);
1927 if(local_unknown >= 0)
1929 jacobian(local_eqn,local_unknown)
1930 += dpsifdx(l2,i2)*testp[l]*
W;
1948 template<
unsigned DIM>
1951 double*
const ¶meter_pt,
1958 OOMPH_CURRENT_FUNCTION,
1959 OOMPH_EXCEPTION_LOCATION);
1966 template<
unsigned DIM>
1974 "Not yet implemented\n",
1975 OOMPH_CURRENT_FUNCTION,
1976 OOMPH_EXCEPTION_LOCATION);
1986 template <
unsigned DIM>
1989 dresidual_dnodal_coordinates)
1992 if(ndof()==0) {
return; }
1995 const unsigned n_node = nnode();
1998 double time=node_pt(0)->time_stepper_pt()->time_pt()->time();
2001 const unsigned n_pres = npres_nst();
2004 unsigned u_nodal_index[DIM];
2005 for(
unsigned i=0;
i<DIM;
i++) { u_nodal_index[
i] = u_index_nst(
i); }
2008 Shape psif(n_node), testf(n_node);
2009 DShape dpsifdx(n_node,DIM), dtestfdx(n_node,DIM);
2012 Shape psip(n_pres), testp(n_pres);
2030 const unsigned n_intpt = integral_pt()->nweight();
2037 double scaled_re = re()*density_ratio();
2038 double scaled_re_st = re_st()*density_ratio();
2039 double scaled_re_inv_fr = re_invfr()*density_ratio();
2040 double visc_ratio = viscosity_ratio();
2049 bool element_has_node_with_aux_node_update_fct=
false;
2050 for (
unsigned q=0;q<n_node;q++)
2052 Node* nod_pt=node_pt(q);
2057 element_has_node_with_aux_node_update_fct=
true;
2061 for (
unsigned i=0;
i<DIM;
i++)
2063 u_ref[
i]=*(nod_pt->
value_pt(u_nodal_index[
i]));
2067 for (
unsigned p=0;p<DIM;p++)
2070 double backup=nod_pt->
x(p);
2074 nod_pt->
x(p)+=eps_fd;
2080 d_U_dX(p,q)=(*(nod_pt->
value_pt(u_nodal_index[p]))-u_ref[p])/eps_fd;
2083 nod_pt->
x(p)=backup;
2095 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
2098 for(
unsigned i=0;
i<DIM;
i++) { s[
i] = integral_pt()->knot(ipt,
i); }
2101 const double w = integral_pt()->weight(ipt);
2104 const double J = dshape_and_dtest_eulerian_at_knot_nst(ipt,psif,dpsifdx,
2107 d_dtestfdx_dX,dJ_dX);
2110 pshape_nst(s,psip,testp);
2114 double interpolated_p=0.0;
2122 for(
unsigned l=0;l<n_pres;l++) { interpolated_p += p_nst(l)*psip[l]; }
2127 for(
unsigned l=0;l<n_node;l++)
2130 for(
unsigned i=0;
i<DIM;
i++)
2133 double u_value = raw_nodal_value(l,u_nodal_index[
i]);
2134 interpolated_u[
i] += u_value*psif[l];
2135 interpolated_x[
i] += raw_nodal_position(l,i)*psif[l];
2136 dudt[
i] += du_dt_nst(l,i)*psif[l];
2139 for(
unsigned j=0;j<DIM;j++)
2141 interpolated_dudx(i,j) += u_value*dpsifdx(l,j);
2149 for(
unsigned l=0;l<n_node;l++)
2152 for(
unsigned i=0;
i<DIM;
i++)
2154 mesh_velocity[
i] += this->raw_dnodal_position_dt(l,
i)*psif[l];
2160 for(
unsigned q=0;q<n_node;q++)
2163 for(
unsigned p=0;p<DIM;p++)
2165 for(
unsigned i=0;
i<DIM;
i++)
2167 for(
unsigned k=0;k<DIM;k++)
2170 for(
unsigned j=0;j<n_node;j++)
2173 raw_nodal_value(j,u_nodal_index[
i])*d_dpsifdx_dX(p,q,j,k);
2175 d_dudx_dX(p,q,
i,k) = aux;
2183 const double pos_time_weight
2184 = node_pt(0)->position_time_stepper_pt()->weight(1,0);
2185 const double val_time_weight = node_pt(0)->time_stepper_pt()->weight(1,0);
2189 get_body_force_nst(time,ipt,s,interpolated_x,body_force);
2192 const double source = get_source_nst(time,ipt,interpolated_x);
2199 get_body_force_gradient_nst(
2200 time,ipt,s,interpolated_x,d_body_force_dx);
2204 get_source_gradient_nst(time,ipt,interpolated_x,source_gradient);
2214 for(
unsigned l=0;l<n_node;l++)
2218 for(
unsigned i=0;
i<DIM;
i++)
2221 local_eqn = nodal_local_eqn(l,u_nodal_index[
i]);;
2227 for (
unsigned p=0;p<DIM;p++)
2230 for (
unsigned q=0;q<n_node;q++)
2237 double sum = body_force[
i]*testf[l];
2240 sum += scaled_re_inv_fr*testf[l]*G[
i];
2243 sum += interpolated_p*dtestfdx(l,i);
2249 for(
unsigned k=0;k<DIM;k++)
2252 (interpolated_dudx(i,k) + Gamma[
i]*interpolated_dudx(k,i))
2259 sum -= scaled_re_st*dudt[
i]*testf[l];
2262 for(
unsigned k=0;k<DIM;k++)
2264 double tmp=scaled_re*interpolated_u[k];
2266 sum -= tmp*interpolated_dudx(i,k)*testf[l];
2270 dresidual_dnodal_coordinates(local_eqn,p,q)+=sum*dJ_dX(p,q)*w;
2276 sum=d_body_force_dx(i,p)*psif(q)*testf(l);
2279 sum += interpolated_p*d_dtestfdx_dX(p,q,l,i);
2282 for (
unsigned k=0;k<DIM;k++)
2285 (interpolated_dudx(i,k) + Gamma[
i]*interpolated_dudx(k,i))
2286 *d_dtestfdx_dX(p,q,l,k)+
2287 (d_dudx_dX(p,q,i,k) + Gamma[
i]*d_dudx_dX(p,q,k,i))
2292 for(
unsigned k=0;k<DIM;k++)
2294 double tmp=scaled_re*interpolated_u[k];
2296 sum -= tmp*d_dudx_dX(p,q,i,k)*testf(l);
2300 sum+=scaled_re_st*pos_time_weight*
2301 psif(q)*interpolated_dudx(i,p)*testf(l);
2305 dresidual_dnodal_coordinates(local_eqn,p,q)+=sum*J*w;
2309 if(element_has_node_with_aux_node_update_fct)
2311 sum=-visc_ratio*Gamma[
i]*dpsifdx(q,i)*dtestfdx(l,p)
2312 -scaled_re*psif(q)*interpolated_dudx(i,p)*testf(l);
2315 sum-=scaled_re_st*val_time_weight*psif(q)*testf(l);
2316 for (
unsigned k=0;k<DIM;k++)
2318 sum-=visc_ratio*dpsifdx(q,k)*dtestfdx(l,k);
2319 double tmp=scaled_re*interpolated_u[k];
2321 sum-=tmp*dpsifdx(q,k)*testf(l);
2324 dresidual_dnodal_coordinates(local_eqn,p,q)+=
2325 sum*d_U_dX(p,q)*J*w;
2338 for(
unsigned l=0;l<n_pres;l++)
2340 local_eqn = p_local_eqn(l);
2347 for (
unsigned p=0;p<DIM;p++)
2350 for (
unsigned q=0;q<n_node;q++)
2360 for(
unsigned k=0;k<DIM;k++)
2362 aux += interpolated_dudx(k,k);
2366 dresidual_dnodal_coordinates(local_eqn,p,q)+=
2367 aux*dJ_dX(p,q)*testp[l]*w;
2373 aux=-source_gradient[p]*psif(q);
2374 for(
unsigned k=0;k<DIM;k++)
2376 aux += d_dudx_dX(p,q,k,k);
2379 dresidual_dnodal_coordinates(local_eqn,p,q)+=
2384 if(element_has_node_with_aux_node_update_fct)
2386 aux=dpsifdx(q,p)*testp(l);
2387 dresidual_dnodal_coordinates(local_eqn,p,q)+=
2388 aux*d_U_dX(p,q)*J*w;
2413 ={2,2,2,2,2,2,2,2,2};
2419 ={3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3};
2425 template<
unsigned DIM>
2427 {
return Initial_Nvalue[n];}
2439 template<
unsigned DIM>
2444 unsigned u_index[DIM];
2445 for(
unsigned i=0;
i<DIM;
i++) {u_index[
i] = this->u_index_nst(
i);}
2448 unsigned n_node = this->nnode();
2449 for(
unsigned n=0;n<n_node;n++)
2453 for(
unsigned i=0;
i<DIM;
i++)
2455 paired_load_data.insert(std::make_pair(this->node_pt(n),u_index[
i]));
2460 identify_pressure_data(paired_load_data);
2474 template<
unsigned DIM>
2479 unsigned n_internal = this->ninternal_data();
2480 for(
unsigned l=0;l<n_internal;l++)
2482 unsigned nval=this->internal_data_pt(l)->nvalue();
2484 for (
unsigned j=0;j<nval;j++)
2486 paired_pressure_data.insert(std::make_pair(this->internal_data_pt(l),j));
2500 template<
unsigned DIM>
2502 std::list<std::pair<unsigned long,unsigned> >& dof_lookup_list)
const 2505 unsigned n_node = this->nnode();
2508 unsigned n_press = this->npres_nst();
2511 std::pair<unsigned,unsigned> dof_lookup;
2514 unsigned pressure_dof_number = DIM;
2517 for (
unsigned n = 0; n < n_press; n++)
2520 int local_eqn_number = this->p_local_eqn(n);
2525 if (local_eqn_number >= 0)
2529 dof_lookup.first = this->eqn_number(local_eqn_number);
2530 dof_lookup.second = pressure_dof_number;
2533 dof_lookup_list.push_front(dof_lookup);
2538 for (
unsigned n = 0; n < n_node; n++)
2541 unsigned nv = this->node_pt(n)->nvalue();
2544 for (
unsigned v = 0; v < nv; v++)
2547 int local_eqn_number = this->nodal_local_eqn(n, v);
2550 if (local_eqn_number >= 0)
2554 dof_lookup.first = this->eqn_number(local_eqn_number);
2555 dof_lookup.second = v;
2558 dof_lookup_list.push_front(dof_lookup);
2586 const unsigned QTaylorHoodElement<3>::Initial_Nvalue[27]={4,3,4,3,3,3,4,3,4,3,3,3,3,3,3,3,3,3,4,3,4,3,3,3,4,3,4};
2601 template<
unsigned DIM>
2606 unsigned u_index[DIM];
2607 for(
unsigned i=0;
i<DIM;
i++) {u_index[
i] = this->u_index_nst(
i);}
2610 unsigned n_node = this->nnode();
2611 for(
unsigned n=0;n<n_node;n++)
2615 for(
unsigned i=0;
i<DIM;
i++)
2617 paired_load_data.insert(std::make_pair(this->node_pt(n),u_index[
i]));
2622 this->identify_pressure_data(paired_load_data);
2635 template<
unsigned DIM>
2640 unsigned p_index =
static_cast<unsigned>(this->p_nodal_index_nst());
2643 unsigned n_pres= npres_nst();
2644 for(
unsigned l=0;l<n_pres;l++)
2648 paired_pressure_data.insert(std::make_pair(this->node_pt(Pconv[l]),p_index));
2661 template<
unsigned DIM>
2663 std::list<std::pair<
unsigned long,
2664 unsigned> >& dof_lookup_list)
const 2667 unsigned n_node = this->nnode();
2673 std::pair<unsigned,unsigned> dof_lookup;
2676 for (
unsigned n = 0; n < n_node; n++)
2679 unsigned nv = this->required_nvalue(n);
2682 for (
unsigned v = 0; v < nv; v++)
2685 int local_eqn_number = this->nodal_local_eqn(n, v);
2690 if (local_eqn_number >= 0)
2694 dof_lookup.first = this->eqn_number(local_eqn_number);
2697 dof_lookup.second = v;
2700 dof_lookup_list.push_front(dof_lookup);
bool ALE_is_disabled
Boolean flag to indicate if ALE formulation is disabled when time-derivatives are computed...
unsigned long nrow() const
Return the number of rows of the matrix.
void full_output(std::ostream &outfile)
Full output function: x,y,[z],u,v,[w],p,du/dt,dv/dt,[dw/dt],dissipation in tecplot format...
void get_dof_numbers_for_unknowns(std::list< std::pair< unsigned long, unsigned > > &dof_lookup_list) const
Create a list of pairs for all unknowns in this element, so that the first entry in each pair contain...
void compute_error(std::ostream &outfile, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt, const double &time, double &error, double &norm)
Validate against exact solution at given time Solution is provided via function pointer. Plot at a given number of plot points and compute L2 error and L2 norm of velocity solution over element.
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...
unsigned long ncol() const
Return the number of columns of the matrix.
void output_vorticity(std::ostream &outfile, const unsigned &nplot)
Output function: x,y,[z], [omega_x,omega_y,[and/or omega_z]] in tecplot format. nplot points in each ...
double * value_pt(const unsigned &i) const
Return the pointer to the i-the stored value. Typically this is required when direct access to the st...
void compute_norm(double &norm)
Compute norm of solution: square of the L2 norm of the velocities.
double kin_energy() const
Get integral of kinetic energy over element.
static Vector< double > Default_Gravity_vector
Static default value for the gravity vector.
void perform_auxiliary_node_update_fct()
Execute auxiliary update function (if any) – this can be used to update any nodal values following t...
static double Default_Physical_Constant_Value
Static default value for the physical constants (all initialised to zero)
void identify_load_data(std::set< std::pair< Data *, unsigned > > &paired_load_data)
Add to the set paired_load_data pairs containing.
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Function pointer for function that computes Vector-valued time-dependent function as ...
virtual unsigned required_nvalue(const unsigned &n) const
Number of values (pinned or dofs) required at local node n.
static double Default_Physical_Ratio_Value
Static default value for the physical ratios (all are initialised to one)
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
void output_fct(std::ostream &outfile, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output exact solution specified via function pointer at a given number of plot points. Function prints as many components as are returned in solution Vector.
void get_dof_numbers_for_unknowns(std::list< std::pair< unsigned long, unsigned > > &dof_lookup_list) const
Create a list of pairs for all unknowns in this element, so that the first entry in each pair contain...
void get_traction(const Vector< double > &s, const Vector< double > &N, Vector< double > &traction)
Compute traction (on the viscous scale) exerted onto the fluid at local coordinate s...
bool has_auxiliary_node_update_fct_pt()
Boolean to indicate if node has a pointer to and auxiliary update function.
virtual void fill_in_generic_dresidual_contribution_nst(double *const ¶meter_pt, Vector< double > &dres_dparam, DenseMatrix< double > &djac_dparam, DenseMatrix< double > &dmass_matrix_dparam, unsigned flag)
Compute the derivatives of the residuals for the Navier–Stokes equations with respect to a parameter...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
static Vector< double > Gamma
Vector to decide whether the stress-divergence form is used or not.
void output_veloc(std::ostream &outfile, const unsigned &nplot, const unsigned &t)
Output function: x,y,[z],u,v,[w] in tecplot format. nplot points in each coordinate direction at time...
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as ...
void fill_in_contribution_to_hessian_vector_products(Vector< double > const &Y, DenseMatrix< double > const &C, DenseMatrix< double > &product)
Compute the hessian tensor vector products required to perform continuation of bifurcations analytica...
virtual void get_dresidual_dnodal_coordinates(RankThreeTensor< double > &dresidual_dnodal_coordinates)
Compute derivatives of elemental residual vector with respect to nodal coordinates. Overwrites default implementation in FiniteElement base class. dresidual_dnodal_coordinates(l,i,j) = d res(l) / dX_{ij}.
virtual void fill_in_generic_pressure_advection_diffusion_contribution_nst(Vector< double > &residuals, DenseMatrix< double > &jacobian, unsigned flag)
Compute the residuals for the associated pressure advection diffusion problem. Used by the Fp precond...
void identify_load_data(std::set< std::pair< Data *, unsigned > > &paired_load_data)
Add to the set paired_load_data pairs containing.
void identify_pressure_data(std::set< std::pair< Data *, unsigned > > &paired_pressure_data)
Add to the set paired_pressure_data pairs containing.
void shape(const double &s, double *Psi)
Definition for 1D Lagrange shape functions. The value of all the shape functions at the local coordin...
void output(std::ostream &outfile)
Output function: x,y,[z],u,v,[w],p in tecplot format. Default number of plot points.
void identify_pressure_data(std::set< std::pair< Data *, unsigned > > &paired_pressure_data)
Add to the set paired_pressure_data pairs containing.
double dissipation() const
Return integral of dissipation over element.
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
void get_vorticity(const Vector< double > &s, Vector< double > &vorticity) const
Compute the vorticity vector at local coordinate s.
void strain_rate(const Vector< double > &s, DenseMatrix< double > &strain_rate) const
Strain-rate tensor: 1/2 (du_i/dx_j + du_j/dx_i)
double pressure_integral() const
Integral of pressure over element.
virtual void fill_in_generic_residual_contribution_nst(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix, unsigned flag)
Compute the residuals for the Navier–Stokes equations. Flag=1 (or 0): do (or don't) compute the Jaco...
static int Pressure_not_stored_at_node
Static "magic" number that indicates that the pressure is not stored at a node.
double d_kin_energy_dt() const
Get integral of time derivative of kinetic energy over element.
static double Default_fd_jacobian_step
Double used for the default finite difference step in elemental jacobian calculations.