33 #ifndef OOMPH_WOMERSLEY_ELEMENTS_HEADER 34 #define OOMPH_WOMERSLEY_ELEMENTS_HEADER 38 #include <oomph-lib-config.h> 43 #include "../generic/nodes.h" 44 #include "../generic/Qelements.h" 45 #include "../generic/mesh.h" 46 #include "../generic/problem.h" 47 #include "../generic/oomph_utilities.h" 48 #include "../navier_stokes/navier_stokes_flux_control_elements.h" 121 virtual double get_volume_flux()=0;
128 virtual void add_element_contribution_to_aux_integral(
129 std::map<unsigned,double>* aux_integral_pt)=0;
134 virtual void set_aux_integral_pt(std::map<unsigned,double>*
141 impedance_tube_pt)=0;
150 virtual void set_external_data_from_navier_stokes_outflow_mesh(
151 Mesh* navier_stokes_outflow_mesh_pt_mesh_pt)=0;
206 template <
unsigned DIM>
215 ReSt_pt = &Default_ReSt_value;
237 if (pressure_gradient_data_pt->
nvalue()!=1)
240 "Pressure gradient Data must only contain a single value!\n",
241 OOMPH_CURRENT_FUNCTION,
242 OOMPH_EXCEPTION_LOCATION);
245 Pressure_gradient_data_pt=pressure_gradient_data_pt;
253 return Pressure_gradient_data_pt;
258 const double &
re_st()
const {
return *ReSt_pt;}
280 TimeStepper* time_stepper_pt= this->node_pt(n)->time_stepper_pt();
289 const unsigned u_nodal_index = u_index_womersley();
292 const unsigned n_time = time_stepper_pt->
ntstorage();
295 for(
unsigned t=0;
t<n_time;
t++)
297 dudt += time_stepper_pt->
weight(1,
t)*nodal_value(
t,n,u_nodal_index);
313 void output_3d(std::ostream &outfile,
314 const unsigned &n_plot,
315 const double& z_out);
319 void output(std::ostream &outfile,
const unsigned &nplot);
332 void output(FILE* file_pt,
const unsigned &n_plot);
336 void output_fct(std::ostream &outfile,
const unsigned &nplot,
344 void output_fct(std::ostream &outfile,
const unsigned &nplot,
354 double& error,
double& norm);
361 const double& time,
double& error,
double& norm);
367 unsigned n_node = nnode();
370 unsigned u_nodal_index = u_index_womersley();
374 DShape dpsidx(n_node,DIM);
377 dshape_eulerian(s,psi,dpsidx);
380 for(
unsigned j=0;j<DIM;j++) {flux[j] = 0.0;}
383 for(
unsigned l=0;l<n_node;l++)
386 for(
unsigned j=0;j<DIM;j++)
388 flux[j] += nodal_value(l,u_nodal_index)*dpsidx(l,j);
399 fill_in_generic_residual_contribution_womersley(
409 fill_in_generic_residual_contribution_womersley(residuals,jacobian,1);
417 unsigned n_node = nnode();
420 unsigned u_nodal_index = u_index_womersley();
429 double interpolated_u = 0.0;
432 for(
unsigned l=0;l<n_node;l++)
434 interpolated_u += nodal_value(l,u_nodal_index)*psi[l];
437 return(interpolated_u);
444 double get_volume_flux();
450 virtual double dshape_and_dtest_eulerian_womersley(
const Vector<double> &
s,
459 virtual double dshape_and_dtest_eulerian_at_knot_womersley(
469 virtual void fill_in_generic_residual_contribution_womersley(
484 template<
unsigned DIMM>
501 Data* pressure_gradient_data_pt)
503 Pressure_gradient_data_pt=pressure_gradient_data_pt;
504 add_external_data(pressure_gradient_data_pt);
526 template<
unsigned DIM>
537 double* prescribed_flux_pt) :
538 Prescribed_flux_pt(prescribed_flux_pt)
541 Womersley_mesh_pt=womersley_mesh_pt;
544 Pressure_gradient_data_pt=
new Data(1);
545 Pressure_gradient_data_pt->set_value(0,0.0);
548 add_internal_data(Pressure_gradient_data_pt);
552 unsigned n_element = womersley_mesh_pt->
nelement();
557 for(
unsigned e=0;
e<n_element;
e++)
565 Pressure_gradient_data_pt);
575 return Pressure_gradient_data_pt;
586 unsigned nelem=Womersley_mesh_pt->nelement();
587 for (
unsigned e=0;
e<nelem;
e++)
606 int local_eqn=internal_local_eqn(0,0);
609 residuals[local_eqn]+=total_volume_flux()-(*Prescribed_flux_pt);
623 unsigned n_dof=ndof();
624 for (
unsigned i=0;
i<n_dof;
i++)
626 for (
unsigned j=0;j<n_dof;j++)
632 get_residuals(residuals);
662 template <
unsigned DIM,
unsigned NNODE_1D>
695 {
return Initial_Nvalue;}
705 void output(std::ostream &outfile,
const unsigned &n_plot)
718 void output(FILE* file_pt,
const unsigned &n_plot)
724 void output_fct(std::ostream &outfile,
const unsigned &n_plot,
734 void output_fct(std::ostream &outfile,
const unsigned &n_plot,
744 inline double dshape_and_dtest_eulerian_womersley(
const Vector<double> &
s,
753 inline double dshape_and_dtest_eulerian_at_knot_womersley(
const unsigned &ipt,
771 template<
class ELEMENT,
unsigned DIM>
779 typedef double (*PrescribedPressureGradientFctPt)(
const double& time);
791 double* prescribed_volume_flux_pt,
793 Mesh* womersley_mesh_pt);
804 PrescribedPressureGradientFctPt pressure_gradient_fct_pt,
806 Mesh* womersley_mesh_pt);
823 if (Prescribed_pressure_gradient_fct_pt!=0)
825 Pressure_gradient_data_pt->set_value(
826 0,Prescribed_pressure_gradient_fct_pt(time_pt()->time()));
832 void doc_solution(
DocInfo& doc_info,
833 std::ofstream& trace_file,
834 const double& z_out=0.0);
838 const double& z_out=0.0)
840 std::ofstream trace_file;
841 doc_solution(doc_info,trace_file,z_out);
848 return Pressure_gradient_data_pt;
883 template<
class ELEMENT,
unsigned DIM>
886 PrescribedPressureGradientFctPt pressure_gradient_fct_pt,
888 Mesh* womersley_mesh_pt) :
889 Prescribed_volume_flux_pt(0),
891 Prescribed_pressure_gradient_fct_pt(pressure_gradient_fct_pt)
895 Problem_is_nonlinear=
false;
898 add_time_stepper_pt(time_stepper_pt);
901 mesh_pt() = womersley_mesh_pt;
907 unsigned n_element = mesh_pt()->
nelement();
911 for(
unsigned i=0;
i<n_element;
i++)
914 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(mesh_pt()->element_pt(
i));
917 el_pt->re_st_pt()=re_st_pt;
921 Pressure_gradient_data_pt=
new Data(1);
922 Pressure_gradient_data_pt->pin(0);
925 unsigned nelem=mesh_pt()->nelement();
926 for (
unsigned e=0;
e<nelem;
e++)
928 ELEMENT* el_pt=
dynamic_cast<ELEMENT*
>(mesh_pt()->element_pt(
e));
931 el_pt->set_pressure_gradient_pt(Pressure_gradient_data_pt);
937 oomph_info <<
"Number of equations in WomersleyProblem: " 938 << assign_eqn_numbers() << std::endl;
955 template<
class ELEMENT,
unsigned DIM>
958 double* prescribed_volume_flux_pt,
960 Mesh* womersley_mesh_pt) :
961 Prescribed_volume_flux_pt(prescribed_volume_flux_pt),
963 Prescribed_pressure_gradient_fct_pt(0)
966 Problem_is_nonlinear=
false;
969 add_time_stepper_pt(time_stepper_pt);
972 mesh_pt() = womersley_mesh_pt;
979 unsigned n_element = mesh_pt()->
nelement();
983 for(
unsigned i=0;
i<n_element;
i++)
986 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(mesh_pt()->element_pt(
i));
989 el_pt->re_st_pt()=re_st_pt;
998 mesh_pt(),Prescribed_volume_flux_pt);
1001 mesh_pt()->add_element_pt(Flux_el_pt);
1008 oomph_info <<
"Number of equations in WomersleyProblem: " 1009 << assign_eqn_numbers() << std::endl;
1017 template<
class ELEMENT,
unsigned DIM>
1031 template<
class ELEMENT,
unsigned DIM>
1034 std::ofstream& trace_file,
1035 const double& z_out)
1038 std::ofstream some_file;
1039 std::ofstream some_file1;
1040 std::ostringstream filename;
1052 filename << doc_info.
directory() <<
"/womersley_soln" 1053 << doc_info.
number() <<
".dat";
1054 some_file1.open(filename.str().c_str());
1057 filename << doc_info.
directory() <<
"/womersley_soln_3d_" 1058 << doc_info.
number() <<
".dat";
1059 some_file.open(filename.str().c_str());
1062 unsigned nelem=mesh_pt()->nelement();
1063 for (
unsigned e=0;
e<nelem;
e++)
1065 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(mesh_pt()->element_pt(
e));
1068 flux+=el_pt->get_volume_flux();
1069 el_pt->output_3d(some_file,npts,z_out);
1070 el_pt->output(some_file1,npts);
1076 double prescribed_g=0.0;
1077 if (Prescribed_pressure_gradient_fct_pt!=0)
1079 prescribed_g=Prescribed_pressure_gradient_fct_pt(time_pt()->time());
1083 double prescribed_q=0.0;
1084 if (Prescribed_volume_flux_pt!=0)
1086 prescribed_q=*Prescribed_volume_flux_pt;
1089 if (trace_file.is_open())
1092 << time_pt()->time() <<
" " 1093 << pressure_gradient_data_pt()->value(0) <<
" " 1095 << prescribed_g <<
" " 1096 << prescribed_q <<
" " 1119 template<
class ELEMENT,
unsigned DIM>
1128 typedef double (*PrescribedVolumeFluxFctPt)(
const double& time);
1134 const double& length,
1135 PrescribedVolumeFluxFctPt prescribed_volume_flux_fct_pt) :
1138 Prescribed_volume_flux_fct_pt(prescribed_volume_flux_fct_pt),
1139 Navier_stokes_outflow_mesh_pt(0)
1142 Current_volume_flux_pt=
new double(0.0);
1157 const double& length,
1158 Mesh* navier_stokes_outflow_mesh_pt) :
1161 Prescribed_volume_flux_fct_pt(0),
1162 Navier_stokes_outflow_mesh_pt(navier_stokes_outflow_mesh_pt)
1165 Current_volume_flux_pt=
new double(0.0);
1169 Using_flux_control_elements=
true;
1172 if (dynamic_cast<NavierStokesImpedanceTractionElementBase*>(
1173 navier_stokes_outflow_mesh_pt->
element_pt(0)))
1175 Using_flux_control_elements=
false;
1182 Aux_integral_pt=
new std::map<unsigned,double>;
1186 unsigned nelem=navier_stokes_outflow_mesh_pt->
nelement();
1187 for (
unsigned e=0;
e<nelem;
e++)
1199 navier_stokes_outflow_mesh_pt);
1206 if (!dynamic_cast<TemplateFreeNavierStokesFluxControlElementBase*>(
1207 navier_stokes_outflow_mesh_pt->
element_pt(0)))
1209 std::ostringstream error_message;
1210 error_message <<
"WomersleyImpedanceTubeBase requires a Navier-Stokes\n" 1211 <<
"outflow mesh of elements which inherit from either\n" 1212 <<
"TemplateFreeNavierStokesFluxControlElementBase or\n" 1213 <<
"NavierStokesImpedanceTractionElementBase.\n";
1215 error_message.str(),
1216 OOMPH_CURRENT_FUNCTION,
1217 OOMPH_EXCEPTION_LOCATION);
1241 double* re_st_pt=&
Zero;
1244 TimeStepper* time_stepper_pt=&Mesh::Default_TimeStepper;
1245 setup(re_st_pt,dt,q_initial,time_stepper_pt);
1260 const double& q_initial,
1264 if (time_stepper_pt==0)
1266 time_stepper_pt=
new BDF<2>;
1270 Mesh* my_mesh_pt=build_mesh_and_apply_boundary_conditions(time_stepper_pt);
1273 Womersley_problem_pt=
1275 time_stepper_pt,my_mesh_pt);
1281 <<
"NOTE: We're suppressing timings etc from \n" 1282 <<
" Newton solver in WomersleyImpedanceTubeBase. " 1287 if ((!Using_flux_control_elements) && (Navier_stokes_outflow_mesh_pt!=0))
1289 precompute_aux_integrals();
1294 Womersley_problem_pt->initialise_dt(dt);
1297 *Current_volume_flux_pt=q_initial;
1303 Womersley_problem_pt->linear_solver_pt()->enable_resolve();
1306 Womersley_problem_pt->enable_jacobian_reuse();
1309 Womersley_problem_pt->linear_solver_pt()->disable_doc_time();
1315 unsigned n_dof=Womersley_problem_pt->ndof();
1320 Womersley_problem_pt->linear_solver_pt()->solve(Womersley_problem_pt,dx);
1334 unsigned g_eqn=Womersley_problem_pt->
1335 pressure_gradient_data_pt()->eqn_number(0);
1343 Womersley_problem_pt->linear_solver_pt()->resolve(drdq,dxdq);
1347 Dp_in_dq=dxdq[g_eqn]*Length;
1356 return Womersley_problem_pt;
1367 Womersley_problem_pt->shift_time_values();
1370 Womersley_problem_pt->time_pt()->time()+=dt;
1371 Womersley_problem_pt->time_pt()->dt()=dt;
1374 unsigned n_time_steppers = Womersley_problem_pt->ntime_stepper();
1377 for(
unsigned i=0;
i<n_time_steppers;
i++)
1379 Womersley_problem_pt->time_stepper_pt(
i)->set_weights();
1392 if (Prescribed_volume_flux_fct_pt!=0)
1394 return Prescribed_volume_flux_fct_pt(
1395 Womersley_problem_pt->time_pt()->time());
1399 unsigned nelem=Navier_stokes_outflow_mesh_pt->nelement();
1401 if (Using_flux_control_elements)
1403 for (
unsigned e=0;
e<nelem;
e++)
1406 Navier_stokes_outflow_mesh_pt->element_pt(
e))->get_volume_flux();
1411 for (
unsigned e=0;
e<nelem;
e++)
1414 Navier_stokes_outflow_mesh_pt->element_pt(
e))->get_volume_flux();
1432 *Current_volume_flux_pt=total_volume_flux_into_impedance_tube();
1436 Womersley_problem_pt->newton_solve();
1440 p_in=-Womersley_problem_pt->pressure_gradient_data_pt()->value(0)*Length+
1457 unsigned nelem=Navier_stokes_outflow_mesh_pt->nelement();
1458 for (
unsigned e=0;
e<nelem;
e++)
1462 Navier_stokes_outflow_mesh_pt->element_pt(
e));
1474 for (
unsigned e=0;
e<nelem;
e++)
1479 Navier_stokes_outflow_mesh_pt->element_pt(
e));
1543 template<
unsigned DIM,
unsigned NNODE_1D>
1552 double J = this->dshape_eulerian(s,psi,dpsidx);
1556 for(
unsigned i=0;
i<NNODE_1D;
i++)
1559 for(
unsigned j=0;j<DIM;j++)
1561 dtestdx(
i,j) = dpsidx(
i,j);
1576 template<
unsigned DIM,
unsigned NNODE_1D>
1579 const unsigned &ipt,
1586 double J = this->dshape_eulerian_at_knot(ipt,psi,dpsidx);
1609 template<
unsigned DIM,
unsigned NNODE_1D>
1611 public virtual QElement<DIM-1,NNODE_1D>
1631 template<
unsigned NNODE_1D>
1674 template <
class WOMERSLEY_ELEMENT>
1692 const unsigned& fixed_coordinate,
1693 const unsigned& w_index)
1696 unsigned nelem=n_st_outflow_mesh_pt->
nelement();
1702 std::set<Node*> n_st_nodes;
1703 for (
unsigned e=0;
e<nelem;
e++)
1706 unsigned nnod_el=el_pt->
nnode();
1707 for (
unsigned j=0;j<nnod_el;j++)
1709 n_st_nodes.insert(el_pt->
node_pt(j));
1715 "Cannot build WomersleyMesh from mesh with hanging nodes!",
1716 OOMPH_CURRENT_FUNCTION,
1717 OOMPH_EXCEPTION_LOCATION);
1723 unsigned nnode_n_st= n_st_nodes.size();
1727 Node_pt.resize(nnode_n_st);
1730 for (
unsigned e=0;
e<nelem;
e++)
1732 add_element_pt(
new WOMERSLEY_ELEMENT);
1734 if (finite_element_pt(
e)->nnode()!=
1738 "Number of nodes in existing and new elements don't match",
1739 OOMPH_CURRENT_FUNCTION,
1740 OOMPH_EXCEPTION_LOCATION);
1747 std::map<Node*,bool> n_st_node_done;
1751 std::map<Node*,Node*> equivalent_womersley_node_pt;
1754 unsigned node_count=0;
1764 unsigned n_pinned_nodes=0;
1768 for (
unsigned e=0;
e<nelem;
e++)
1771 unsigned nnod_el=n_st_el_pt->
nnode();
1772 for (
unsigned j=0;j<nnod_el;j++)
1778 if (!n_st_node_done[n_st_node_pt])
1782 finite_element_pt(
e)->construct_node(j,time_stepper_pt);
1785 Node_pt[node_count]=new_node_pt;
1790 unsigned dim=n_st_node_pt->
ndim();
1792 for (
unsigned i=0;
i<dim;
i++)
1794 if (
i!=fixed_coordinate)
1796 new_node_pt->
x(icount)=n_st_node_pt->x(
i);
1802 if (n_st_node_pt->is_pinned(w_index))
1804 new_node_pt->
pin(0);
1810 new_node_pt->
unpin(0);
1815 equivalent_womersley_node_pt[n_st_node_pt]=new_node_pt;
1818 n_st_node_done[n_st_node_pt]=
true;
1824 finite_element_pt(
e)->node_pt(j)=
1825 equivalent_womersley_node_pt[n_st_node_pt];
1830 finite_element_pt(
e)->check_J_eulerian_at_knots(passed);
1834 unsigned nnod=finite_element_pt(
e)->nnode();
1836 for (
unsigned j=0;j<nnod;j++)
1838 orig_nod_pt[j]=finite_element_pt(
e)->node_pt(j);
1840 for (
unsigned j=0;j<nnod;j++)
1842 finite_element_pt(
e)->node_pt(j)=orig_nod_pt[nnod-j-1];
1845 finite_element_pt(
e)->check_J_eulerian_at_knots(passed);
1849 "Element remains inverted even after reversing the local node numbers",
1850 OOMPH_CURRENT_FUNCTION,
1851 OOMPH_EXCEPTION_LOCATION);
1858 if (!Suppress_warning_about_unpinned_nst_dofs)
1860 if (n_pinned_nodes==0)
1862 std::stringstream bla;
1863 bla <<
"Boundary conditions must be applied in Navier-Stokes\n" 1864 <<
"problem before attaching impedance elements.\n" 1865 <<
"Note: This warning can be suppressed by setting the\n" 1866 <<
"global static boolean\n\n" 1867 <<
" TemplateFreeWomersleyMeshBase::Suppress_warning_about_unpinned_nst_dofs\n\n" 1870 OOMPH_CURRENT_FUNCTION,
1871 OOMPH_EXCEPTION_LOCATION);
1877 if (nnode()!=nnode_n_st)
1880 "Number of nodes in the new mesh don't match that in the old one",
1881 OOMPH_CURRENT_FUNCTION,
1882 OOMPH_EXCEPTION_LOCATION);
1901 template<
class ELEMENT,
unsigned DIM>
1918 const double& length,
1919 Mesh* navier_stokes_outflow_mesh_pt,
1920 const unsigned& fixed_coordinate,
1921 const unsigned& w_index) :
1923 navier_stokes_outflow_mesh_pt),
1924 Fixed_coordinate(fixed_coordinate), W_index(w_index)
1938 this->Navier_stokes_outflow_mesh_pt,
1943 return womersley_mesh_pt;
2053 template <
class BULK_NAVIER_STOKES_ELEMENT,
2054 class WOMERSLEY_ELEMENT,
2057 public virtual FaceGeometry<BULK_NAVIER_STOKES_ELEMENT>,
2082 {
return nodal_local_eqn(n,i);}
2091 unsigned n_node = nnode();
2094 shape_at_knot(ipt,psi);
2097 for(
unsigned i=0;
i<n_node;
i++) {test[
i] = psi[
i];}
2100 return J_eulerian_at_knot(ipt);
2107 void fill_in_generic_residual_contribution_fluid_traction(
2118 const int &face_index) :
2130 Navier_stokes_outflow_mesh_pt=0;
2133 Impedance_tube_pt=0;
2144 BULK_NAVIER_STOKES_ELEMENT* elem_pt =
2145 dynamic_cast<BULK_NAVIER_STOKES_ELEMENT*
>(element_pt);
2147 if(elem_pt->dim()==3)
2153 if (this->has_hanging_nodes())
2156 "This flux element will not work correctly if nodes are hanging\n",
2157 OOMPH_CURRENT_FUNCTION,
2158 OOMPH_EXCEPTION_LOCATION);
2175 return Navier_stokes_outflow_mesh_pt;
2182 double volume_flux_integral=0.0;
2194 unsigned n_intpt = integral_pt()->nweight();
2197 BULK_NAVIER_STOKES_ELEMENT* bulk_el_pt=
2198 dynamic_cast<BULK_NAVIER_STOKES_ELEMENT*
>(bulk_element_pt());
2201 for (
unsigned ipt=0;ipt<n_intpt;ipt++)
2205 for(
unsigned i=0;
i<DIM;
i++)
2207 s[
i] = integral_pt()->knot(ipt,
i);
2211 this->get_local_coordinate_in_bulk(s,s_bulk);
2214 double w = integral_pt()->weight(ipt);
2217 double J=J_eulerian(s);
2226 interpolated_x(s,x);
2230 bulk_el_pt->interpolated_x(s_bulk,x_bulk);
2232 double max_legal_error=1.0e-12;
2234 for(
unsigned i=0;
i<DIM+1;
i++)
2236 error+=std::fabs(x[
i]- x_bulk[
i]);
2238 if (error>max_legal_error)
2240 std::ostringstream error_stream;
2241 error_stream <<
"difference in Eulerian posn from bulk and face: " 2242 << error <<
" exceeds threshold " << max_legal_error
2246 OOMPH_CURRENT_FUNCTION,
2247 OOMPH_EXCEPTION_LOCATION);
2253 outer_unit_normal(s,normal);
2257 bulk_el_pt->interpolated_u_nst(s_bulk,veloc);
2260 double volume_flux=0.0;
2261 for (
unsigned i=0;
i<DIM+1;
i++)
2263 volume_flux+=normal[
i]*veloc[
i];
2267 volume_flux_integral+=volume_flux*
W;
2271 return volume_flux_integral;
2282 Mesh* navier_stokes_outflow_mesh_pt)
2288 Navier_stokes_outflow_mesh_pt=navier_stokes_outflow_mesh_pt;
2291 std::set<Data*> external_data_set;
2292 unsigned nelem=Navier_stokes_outflow_mesh_pt->
nelement();
2293 for (
unsigned e=0;
e<nelem;
e++)
2295 FiniteElement* el_pt=Navier_stokes_outflow_mesh_pt->finite_element_pt(
e);
2296 unsigned nnod=el_pt->
nnode();
2297 for (
unsigned j=0;j<nnod;j++)
2299 external_data_set.insert(el_pt->
node_pt(j));
2304 unsigned nnod=nnode();
2305 for (
unsigned j=0;j<nnod;j++)
2307 external_data_set.erase(node_pt(j));
2311 for (std::set<Data*>::iterator it=external_data_set.begin();
2312 it!=external_data_set.end();it++)
2314 add_external_data(*it);
2325 Aux_integral_pt=aux_integral_pt;
2336 if (Navier_stokes_outflow_mesh_pt==0)
2339 "Navier_stokes_outflow_mesh_pt==0 -- set it with \n set_external_data_from_navier_stokes_outflow_mesh() before calling this function!\n",
2340 OOMPH_CURRENT_FUNCTION,
2341 OOMPH_EXCEPTION_LOCATION); }
2345 double total_flux=0.0;
2346 unsigned nelem=Navier_stokes_outflow_mesh_pt->nelement();
2347 for (
unsigned e=0;
e<nelem;
e++)
2350 WOMERSLEY_ELEMENT,DIM>* el_pt=
2353 WOMERSLEY_ELEMENT,DIM
>*>(
2354 Navier_stokes_outflow_mesh_pt->element_pt(
e));
2366 Impedance_tube_pt=
dynamic_cast< 2385 unsigned nnod=nnode();
2389 unsigned n_intpt = integral_pt()->nweight();
2392 for (
unsigned ipt=0;ipt<n_intpt;ipt++)
2396 for(
unsigned i=0;
i<DIM;
i++)
2398 s[
i] = integral_pt()->knot(ipt,
i);
2402 double w = integral_pt()->weight(ipt);
2405 double J=J_eulerian(s);
2415 outer_unit_normal(s,normal);
2418 for (
unsigned j=0;j<nnod;j++)
2421 Node* nod_pt=node_pt(j);
2424 for (
unsigned i=0;
i<(DIM+1);
i++)
2432 (*aux_integral_pt)[i_global]+=psi[j]*normal[
i]*
W;
2446 fill_in_generic_residual_contribution_fluid_traction(
2447 residuals,GeneralisedElement::Dummy_matrix,0);
2457 fill_in_generic_residual_contribution_fluid_traction(residuals,jacobian,1);
2467 const unsigned &
i)
const 2468 {
return FaceElement::zeta_nodal(n,k,i);}
2475 void output(std::ostream &outfile,
const unsigned &nplot)
2492 template <
class BULK_NAVIER_STOKES_ELEMENT,
2493 class WOMERSLEY_ELEMENT,
2498 fill_in_generic_residual_contribution_fluid_traction(
2504 unsigned n_node = nnode();
2507 Shape psif(n_node), testf(n_node);
2510 unsigned n_intpt = integral_pt()->nweight();
2514 int local_unknown=0;
2517 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
2520 double w = integral_pt()->weight(ipt);
2524 double J = shape_and_test_at_knot(ipt,psif,testf);
2534 double dp_in_dq=0.0;
2538 if (Navier_stokes_outflow_mesh_pt!=0)
2541 Impedance_tube_pt->get_response(p_in, dp_in_dq);
2546 outer_unit_normal(ipt, unit_normal);
2549 for(
unsigned i=0;
i<DIM+1;
i++)
2551 traction[
i]=-unit_normal[
i]*p_in;
2556 for(
unsigned l=0;l<n_node;l++)
2560 for(
unsigned i=0;
i<DIM+1;
i++)
2562 local_eqn = u_local_eqn(l,
i);
2567 residuals[local_eqn] += traction[
i]*testf[l]*
W;
2570 if (flag&&(Navier_stokes_outflow_mesh_pt!=0))
2574 for(
unsigned j=0;j<n_node;j++)
2578 Node* nod_pt=node_pt(j);
2581 for(
unsigned ii=0;ii<DIM+1;ii++)
2583 local_unknown = u_local_eqn(j,ii);
2586 if(local_unknown >= 0)
2589 unsigned global_unknown=nod_pt->
eqn_number(ii);
2592 jacobian(local_eqn,local_unknown)-=
2593 (*Aux_integral_pt)[global_unknown]
2594 *psif[l]*unit_normal[
i]*dp_in_dq*
W;
2601 unsigned n_ext=nexternal_data();
2602 for (
unsigned j=0;j<n_ext;j++)
2605 Data* ext_data_pt=external_data_pt(j);
2608 for (
unsigned ii=0;ii<DIM+1;ii++)
2611 int local_unknown=external_local_eqn(j,ii);
2614 if (local_unknown>=0)
2617 unsigned global_unknown=ext_data_pt->
eqn_number(ii);
2620 jacobian(local_eqn,local_unknown)-=
2621 (*Aux_integral_pt)[global_unknown]
2622 *psif[l]*unit_normal[
i]*dp_in_dq*
W;
2664 : Womersley_tube_pt(womersley_tube_pt)
2667 Volume_flux_data_pt =
new Data(1);
2670 Volume_flux_data_id=add_internal_data(Volume_flux_data_pt);
2680 fill_in_generic_residual_contribution_pressure_control(
2682 GeneralisedElement::Dummy_matrix,
2694 fill_in_generic_residual_contribution_pressure_control(residuals,
2706 Pressure_data_id = add_external_data(pressure_data_pt);
2723 std::list<std::pair<unsigned long, unsigned> >& dof_lookup_list)
const 2726 std::pair<unsigned,unsigned> dof_lookup;
2728 dof_lookup.first = this->eqn_number(0);
2729 dof_lookup.second = 0;
2732 dof_lookup_list.push_front(dof_lookup);
2744 const unsigned& flag)
2747 double womersley_pressure=0.0;
2748 double d_womersley_pressure_d_q=0.0;
2751 Womersley_tube_pt->get_response(womersley_pressure,
2752 d_womersley_pressure_d_q);
2755 double pressure = external_data_pt(Pressure_data_id)->value(0);
2758 int local_eq = internal_local_eqn(Volume_flux_data_id,0);
2761 residuals[local_eq] += pressure - womersley_pressure;
2767 int local_unknown = external_local_eqn(Pressure_data_id,0);
2770 jacobian(local_eq,local_eq) -= d_womersley_pressure_d_q;
2771 jacobian(local_eq,local_unknown) += 1.0;
2772 jacobian(local_unknown,local_eq) += 1.0;
2824 Mesh* flux_control_mesh_pt,
2827 flux_control_mesh_pt,
2828 pressure_control_element_pt->volume_flux_data_pt()->value_pt(0))
2849 "NetFluxControlElementForWomersleyPressureControl");
2857 "NetFluxControlElementForWomersleyPressureControl");
2875 std::list<std::pair<unsigned long, unsigned> >& dof_lookup_list)
const 2878 std::pair<unsigned,unsigned> dof_lookup;
2880 dof_lookup.first = this->eqn_number(0);
2881 dof_lookup.second = 0;
2884 dof_lookup_list.push_front(dof_lookup);
NavierStokesWomersleyPressureControlElement(TemplateFreeWomersleyImpedanceTubeBase *womersley_tube_pt)
Constructor takes a pointer to a suitable Womersley impedance tube which defines the pressure via get...
A Generalised Element class.
static const unsigned Initial_Nvalue
Static array of ints to hold number of variables at nodes: Initial_Nvalue[n].
void steady_newton_solve(unsigned const &max_adapt=0)
Solve a steady problem using adaptive Newton's method, but in the context of an overall unstady probl...
void unpin(const unsigned &i)
Unpin the i-th stored variable.
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
void set_impedance_tube_pt(TemplateFreeWomersleyImpedanceTubeBase *impedance_tube_pt)
Set pointer to "impedance tube" that provides the flow resistance.
double P_out
Outlet pressure.
FaceGeometry()
Constructor: Call the constructor for the appropriate lower-dimensional QElement. ...
void output_fct(std::ostream &outfile, const unsigned &n_plot, const double &time, FiniteElement::UnsteadyExactSolutionFctPt exact_soln_pt)
Output function for a time-dependent exact solution. x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot ...
double *& re_st_pt()
Pointer to product of Reynolds and Strouhal number (=Womersley number)
void setup()
Set up the Womersley tubes so that a subsequent call to get_response(...) computes the inlet pressure...
NetFluxControlElementForWomersleyPressureControl(Mesh *flux_control_mesh_pt, NavierStokesWomersleyPressureControlElement *pressure_control_element_pt)
Constructor takes the mesh of TemplateFreeNavierStokesFluxControlElementBase which impose the pressur...
WomersleyProblem< ELEMENT, DIM > * womersley_problem_pt()
Access to underlying Womersley problem.
double * Current_volume_flux_pt
Pointer to double that specifies the currently imposed instantaneous volume flux into the impedance t...
virtual ~NavierStokesImpedanceTractionElementBase()
Empty vitual destructor.
void operator=(const NetFluxControlElementForWomersleyPressureControl &)
Broken assignment operator.
unsigned W_index
The velocity component (in terms of the nodal index) that represents the outflow component – the lat...
unsigned ndof_types() const
The number of "DOF types" that degrees of freedom in this element are sub-divided into - set to 1...
Information for documentation of results: Directory and file number to enable output in the form RESL...
const double & re_st() const
Product of Reynolds and Strouhal number (=Womersley number)
std::string directory() const
Output directory.
Data * set_pressure_gradient_pt() const
Read-only access to pointer to pressure gradient.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Fill in the element's contribution to the element's residual vector and Jacobian matrix.
unsigned ndof_types() const
The number of "DOF types" that degrees of freedom in this element are sub-divided into - set to 1...
void output_fct(std::ostream &outfile, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output exact soln: r,z,u_exact at nplot^2 plot points.
double interpolated_u_womersley(const Vector< double > &s) const
Return FE representation of function value u(s) at local coordinate s.
double du_dt_womersley(const unsigned &n) const
du/dt at local node n. Uses suitably interpolated value for hanging nodes.
NavierStokesImpedanceTractionElement(FiniteElement *const &element_pt, const int &face_index)
WomersleyMesh(Mesh *n_st_outflow_mesh_pt, TimeStepper *time_stepper_pt, const unsigned &fixed_coordinate, const unsigned &w_index)
Constructor: Pass pointer to mesh of face elements in the outflow cross-section of a full Navier-Stok...
void get_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute element residual Vector and element Jacobian matrix Note: Jacobian is zero because the deriva...
ImposeFluxForWomersleyElement< DIM > * Flux_el_pt
Pointer to element that imposes the flux through the collection of Womersley elements.
double Dp_in_dq
Derivative of inflow pressure w.r.t. instantaenous volume flux (Note: Can be pre-computed) ...
A general Finite Element class.
Template-free base class.
Mesh * Womersley_mesh_pt
Pointer to mesh that contains the Womersley elements.
WomersleyProblem(double *re_st_pt, double *prescribed_volume_flux_pt, TimeStepper *time_stepper_pt, Mesh *womersley_mesh_pt)
Constructor: Pass pointer to Womersley number, pointer to the double that stores the currently impose...
void set_pressure_gradient_pt(Data *&pressure_gradient_data_pt)
Set pointer to pressure gradient (single-valued Data)
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Function pointer for function that computes Vector-valued time-dependent function as ...
void get_flux(const Vector< double > &s, Vector< double > &flux) const
Get flux: flux[i] = du/dx_i.
WomersleyEquations()
Constructor: Initialises the Pressure_gradient_data_pt to null.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
Templated class for BDF-type time-steppers with fixed or variable timestep. 1st time derivative recov...
void actions_before_newton_solve()
Update the problem specs before solve (empty)
double total_volume_flux()
Get volume flux through all Womersley elements.
Data * Volume_flux_data_pt
Data object whose single value is the volume flux applied by the elements in the Flux_control_mesh_pt...
bool is_hanging() const
Test whether the node is geometrically hanging.
long & eqn_number(const unsigned &i)
Return the equation number of the i-th stored variable.
WomersleyImpedanceTubeBase(const double &length, PrescribedVolumeFluxFctPt prescribed_volume_flux_fct_pt)
Constructor: Specify length of tube and pointer to function that specifies the prescribed volume flux...
PrescribedVolumeFluxFctPt Prescribed_volume_flux_fct_pt
Pointer to function that specifies the prescribed volume flux.
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
double shape_and_test_at_knot(const unsigned &ipt, Shape &psi, Shape &test) const
Function to compute the shape and test functions and to return the Jacobian of mapping.
WomersleyEquations(const WomersleyEquations &dummy)
Broken copy constructor.
std::map< unsigned, double > * Aux_integral_pt
Pointer to auxiliary integral, containing the derivative of the total volume flux through the outflow...
unsigned Fixed_coordinate
The coordinate (in the higher-dimensional Navier-Stokes mesh) that is constant in the outflow cross-s...
~NetFluxControlElementForWomersleyPressureControl()
Empty Destructor - Data gets deleted automatically.
WomersleyImpedanceTubeBase< WOMERSLEY_ELEMENT, DIM > * Impedance_tube_pt
Pointer to ImpedanceTubeProblem that computes the flow resistance.
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Compute element residual Vector (wrapper)
void pin(const unsigned &i)
Pin the i-th stored variable.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Compute element residual Vector and element Jacobian matrix (wrapper)
WomersleyOutflowImpedanceTube(const double &length, Mesh *navier_stokes_outflow_mesh_pt, const unsigned &fixed_coordinate, const unsigned &w_index)
Constructor: Pass length and mesh of face elements that are attached to the outflow cross-section of ...
void add_element_contribution_to_aux_integral(std::map< unsigned, double > *aux_integral_pt)
void doc_solution(DocInfo &doc_info, const double &z_out=0.0)
Doc the solution.
double get_volume_flux()
Compute total volume flux through element.
unsigned & number()
Number used (e.g.) for labeling output files.
void disable_info_in_newton_solve()
Disable the output of information when in the newton solver.
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Fill in the element's contribution to the element's residual vector.
unsigned long nelement() const
Return number of elements in the mesh.
void output(FILE *file_pt)
C_style output with default number of plot points.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
QWomersleyElement(const QWomersleyElement< DIM, NNODE_1D > &dummy)
Broken copy constructor.
Element to impose volume flux through collection of Womersley elements, in exchange for treating the ...
void setup()
Setup terminate helper.
QWomersleyElement()
Constructor: Call constructors for QElement and Womersley equations.
TemplateFreeWomersleyImpedanceTubeBase * Womersley_tube_pt
Pointer to the Womersley impedance tube.
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Describes the distribution of a distributable linear algebra type object. Typically this is a contain...
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as ...
void precompute_aux_integrals()
Precompute auxiliary integrals required for the computation of the Jacobian in the NavierStokesImpeda...
double Zero
Static variable to hold the default value for the pseudo-solid's inertia parameter Lambda^2...
Mesh * Navier_stokes_outflow_mesh_pt
Pointer to the mesh of NavierStokesImpedanceTractionElements that are attached to the outflow cross-s...
void fill_in_contribution_to_residuals(Vector< double > &residuals)
This function returns the residuals.
unsigned self_test()
Self-test: Return 0 for OK.
NavierStokesImpedanceTractionElementBase()
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
void set_aux_integral_pt(std::map< unsigned, double > *aux_integral_pt)
Set pointer to the precomputed auxiliary integral that contains the derivative of the total volume fl...
double * ReSt_pt
Pointer to global Reynolds number x Strouhal number (=Womersley)
void shift_time_values(const double &dt)
Shift history values to allow coputation of next timestep. Note: When used with a full Navier-Stokes ...
void set_pressure_gradient_and_add_as_external_data(Data *pressure_gradient_data_pt)
Set pointer to pressure gradient (single-valued Data) and treat it as external data – this can only ...
void get_response(double &p_in, double &dp_in_dq)
Compute inlet pressure, p_in, required to achieve the currently imposed, instantaneous volume flux q ...
Mesh *& navier_stokes_outflow_mesh_pt()
Access to mesh containing all NavierStokesImpedanceTractionElements that contribute to the volume flu...
Data * pressure_gradient_data_pt()
Access function to the single-valued Data object that contains the unknown pressure gradient (used if...
void output(std::ostream &outfile)
Output function: x,y,u or x,y,z,u.
double get_volume_flux()
Get integral of volume flux through element.
ImposeFluxForWomersleyElement(Mesh *womersley_mesh_pt, double *prescribed_flux_pt)
Constructor: Pass pointer to mesh that contains the Womersley elements whose volume flux is controlle...
double total_volume_flux_into_downstream_tube()
Compute total volume flux into the "downstream tube" that provides the impedance (computed by adding ...
virtual int u_local_eqn(const unsigned &n, const unsigned &i)
Access function that returns the local equation numbers for velocity components. u_local_eqn(n,i) = local equation number or < 0 if pinned. The default is to asssume that n is the local node number and the i-th velocity component is the i-th unknown stored at the node.
void output_fct(std::ostream &outfile, const unsigned &n_plot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output function for an exact solution: x,y,u_exact or x,y,z,u_exact at n_plot^DIM plot points...
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 setup(double *re_st_pt, const double &dt, const double &q_initial, TimeStepper *time_stepper_pt=0)
Set up the Womersley tubes so that a subsequent call to get_response(...) computes the inlet pressure...
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...
A class that represents a collection of data; each Data object may contain many different individual ...
void output_fct(std::ostream &outfile, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output exact soln: x,y,u_exact or x,y,z,u_exact at nplot^DIM plot points.
Mesh * Navier_stokes_outflow_mesh_pt
Pointer to mesh containing the NavierStokesImpedanceTractionElements that contribute to the volume fl...
unsigned Volume_flux_data_id
Id of internal Data object whose single value is the volume flux.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
void get_residuals(Vector< double > &residuals)
Compute residual vector: the volume flux constraint determines this element's one-and-only internal D...
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 with default number of plot points.
void add_pressure_data(Data *pressure_data_pt)
Function to add to external data the Data object whose single value is the pressure applied at the bo...
Data * volume_flux_data_pt() const
Function to return a pointer to the Data object whose single value is the flux degree of freedom...
unsigned ntstorage() const
Return the number of doubles required to represent history (one for steady)
virtual void set_impedance_tube_pt(TemplateFreeWomersleyImpedanceTubeBase *impedance_tube_pt)=0
Pass the pointer to the "impedance tube" that computes the flow resistance via the solution of Womers...
double & p_out()
Access fct to outlet pressure.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
This function returns the residuals and the Jacobian, plus the Jacobian contribution for the NetFluxC...
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
virtual ~TemplateFreeWomersleyImpedanceTubeBase()
Empty virtual destructor.
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, double &error, double &norm)
Get error against and norm of exact solution.
void actions_after_newton_solve()
Update the problem specs after solve (empty)
double * Prescribed_volume_flux_pt
Pointer to currently prescribed volume flux.
void output(std::ostream &outfile)
Output with default number of plot points.
virtual unsigned u_index_womersley() const
Return the index at which the unknown value is stored. The default value, 0, is appropriate for singl...
virtual void get_response(double &p_in, double &dp_in_dq)=0
Empty virtual dummy member function – every base class needs at least one virtual member function if...
~NavierStokesWomersleyPressureControlElement()
Destructor should not delete anything.
FaceGeometry()
Constructor: Call the constructor for the appropriate lower-dimensional QElement. ...
Data * Pressure_gradient_data_pt
Pointer to single-valued Data item that stores pressure gradient.
void fill_in_generic_residual_contribution_pressure_control(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
This function returns the residuals. flag=1(or 0): do (or don't) compute the Jacobian as well...
void output(std::ostream &outfile, const unsigned &nplot)
Output function: x,y,[z],u,v,[w],p in tecplot format.
double * Prescribed_flux_pt
Pointer to current value of prescribed flux.
virtual void set_aux_integral_pt(std::map< unsigned, double > *aux_integral_pt)=0
Pass the pointer to the pre-computed auxiliary integral to the element so it can be accessed when com...
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...
virtual void set_external_data_from_navier_stokes_outflow_mesh(Mesh *navier_stokes_outflow_mesh_pt_mesh_pt)=0
Pass the pointer to the mesh containing all NavierStokesImpedanceTractionElements that contribute to ...
Data * pressure_gradient_data_pt()
Read-only access to the single-valued Data item that stores the pressure gradient (to be determined v...
WomersleyProblem< ELEMENT, DIM > * Womersley_problem_pt
Pointer to Womersley problem that determines the pressure gradient along the tube.
bool is_steady() const
Flag to indicate if a timestepper has been made steady (possibly temporarily to switch off time-depen...
unsigned required_nvalue(const unsigned &n) const
Required # of `values' (pinned or dofs) at node n.
A vector in the mathematical sense, initially developed for linear algebra type applications. If MPI then this vector can be distributed - its distribution is described by the LinearAlgebraDistribution object at Distribution_pt. Data is stored in a C-style pointer vector (double*)
void set_external_data_from_navier_stokes_outflow_mesh(Mesh *navier_stokes_outflow_mesh_pt)
NavierStokesImpedanceTractionElements that contribute to the volume flux into the downstream "impedan...
void actions_before_implicit_timestep()
Update the problem specs before next timestep: Update time-varying pressure gradient (if prescribed) ...
bool Using_flux_control_elements
unsigned Pressure_data_id
Id of external Data object whose single value is the pressure.
void output(FILE *file_pt)
C-style output function: x,y,u or x,y,z,u.
TemplateFreeWomersleyImpedanceTubeBase()
Empty constructor.
WomersleyImpedanceTubeBase(const double &length, Mesh *navier_stokes_outflow_mesh_pt)
Constructor: Specify length of tube and the pointer to the mesh of either NavierStokesImpedanceTracti...
void output(std::ostream &outfile, const unsigned &n_plot)
Output function: x,y,u or x,y,z,u at n_plot^DIM plot points.
double total_volume_flux_into_impedance_tube()
Compute total current volume flux into the "impedance tube" that provides the flow resistance (flux i...
PrescribedPressureGradientFctPt Prescribed_pressure_gradient_fct_pt
Fct pointer to fct that prescribes pressure gradient.
void operator=(const QWomersleyElement< DIM, NNODE_1D > &)
Broken assignment operator.
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
The "global" intrinsic coordinate of the element when viewed as part of a geometric object should be ...
Data * Pressure_gradient_data_pt
Pointer to pressure gradient Data (single value Data item)
unsigned nnode() const
Return the number of nodes.
Base class for time-stepping schemes. Timestepper provides an approximation of the temporal derivativ...
virtual double weight(const unsigned &i, const unsigned &j) const
Access function for j-th weight for the i-th derivative.
virtual void add_element_contribution_to_aux_integral(std::map< unsigned, double > *aux_integral_pt)=0
Add the element's contribution to the auxiliary integral used in the element's Jacobian. The aux_integral contains the derivative of the total volume flux through the outflow boundary of the (higher-dimensional) Navier-Stokes mesh w.r.t. to the discrete (global) (velocity) degrees of freedom.
~NavierStokesImpedanceTractionElement()
Destructor should not delete anything.
static bool Suppress_warning_about_unpinned_nst_dofs
Static bool to suppress warning.
std::map< unsigned, double > * Aux_integral_pt
Pointer to auxiliary integral, containing the derivative of the total volume flux through the outflow...
Mesh * build_mesh_and_apply_boundary_conditions(TimeStepper *time_stepper_pt)
Implement pure virtual fct (defined in the base class WomersleyImpedanceTubeBase) that builds the mes...
static DenseMatrix< double > Dummy_matrix
Empty dense matrix used as a dummy argument to combined residual and jacobian functions in the case w...
NetFluxControlElementForWomersleyPressureControl(const NetFluxControlElementForWomersleyPressureControl &dummy)
Broken copy constructor.
void output(FILE *file_pt, const unsigned &n_plot)
C-style output function: x,y,u or x,y,z,u at n_plot^DIM plot points.
void operator=(const WomersleyEquations &)
Broken assignment operator.
double Length
Length of the tube.
Data * Pressure_gradient_data_pt
Data item whose one and only value contains the pressure gradient.
static double Default_ReSt_value
Static default value for the Womersley number.
void output(std::ostream &outfile)
Overload the output function.