76  void load(
const Vector<double>& xi, 
const Vector<double>& x,
 
   77            const Vector<double>& N, Vector<double>& 
load)
 
   79   for(
unsigned i=0;i<2;i++) 
 
  170  void position(
const Vector<double>& zeta, Vector<double>& r)
 const 
  181  void position(
const unsigned& t, 
const Vector<double>& zeta,
 
  182                Vector<double>& r)
 const 
  197                          DenseMatrix<double> &drdzeta,
 
  198                          RankThreeTensor<double> &ddrdzeta)
 const 
  257   std::cout << 
"\nFlags:\n" 
  264     std::cout << 
"-- Steady run " << std::endl;
 
  267       std::cout << 
"-- Using displacement control " << std::endl;
 
  271       std::cout << 
"-- Not using displacement control " << std::endl;
 
  276     std::cout << 
"-- Unsteady run " << std::endl;
 
  279       std::cout << 
"-- Not using displacement control (command line flag\n" 
  280                 << 
"   overwritten because it's an unsteady run!) "  
  285   std::cout << 
"-- Reynolds number: "  
  288   std::cout << 
"-- FSI parameter Q: "  
  301     std::cout << 
"-- No restart " << std::endl;
 
  303   std::cout << std::endl;
 
  313 template <
class ELEMENT>
 
  322                               const unsigned& ncollapsible,
 
  323                               const unsigned& ndown,
 
  326                               const double& lcollapsible, 
 
  329                               const bool& displ_control,
 
  330                               const bool& steady_flag);
 
  352     AlgebraicCollapsibleChannelMesh<ELEMENT>*
> 
  389                                   const double& cpu, 
const unsigned &niter);
 
  393                                     const double& cpu, 
const unsigned &niter);
 
  402  void dump_it(ofstream& dump_file);
 
  405  void restart(ifstream& restart_file);
 
  482 template <
class ELEMENT>
 
  485  const unsigned& ncollapsible,
 
  486  const unsigned& ndown,
 
  489  const double& lcollapsible, 
 
  492  const bool& displ_control,
 
  493  const bool& steady_flag)
 
  502  Ncollapsible=ncollapsible;
 
  506  Lcollapsible=lcollapsible;
 
  514    Displ_control=displ_control;
 
  521      std::cout << 
"Switched off displacement control for unsteady run!" 
  528  Problem::Max_residuals=1000.0;
 
  536  add_time_stepper_pt(
new BDF<2>);
 
  539  Steady<2>* wall_time_stepper_pt = 
new Steady<2>;
 
  542  add_time_stepper_pt(wall_time_stepper_pt);
 
  549  Wall_mesh_pt = 
new OneDLagrangianMesh<FSIHermiteBeamElement>
 
  550   (Ncollapsible,Lcollapsible,undeformed_wall_pt,wall_time_stepper_pt);
 
  555   new MeshAsGeomObject(Wall_mesh_pt); 
 
  560  Vector<double> zeta_displ_ctrl(1);
 
  561  zeta_displ_ctrl[0]=3.5;
 
  564    zeta_displ_ctrl[0]=3.0;
 
  569    zeta_displ_ctrl[0]=2.5;
 
  571  std::cout << 
"Wall control point located at zeta=" <<zeta_displ_ctrl[0] 
 
  573  S_displ_ctrl.resize(1);
 
  576  Wall_geom_object_pt->locate_zeta(zeta_displ_ctrl,
 
  583  Displ_control_mesh_pt=
new Mesh;
 
  586  SolidFiniteElement* controlled_element_pt=
 
  587   dynamic_cast<SolidFiniteElement*
>(Ctrl_geom_obj_pt);
 
  590  unsigned controlled_direction=1;
 
  593  DisplacementControlElement* displ_control_el_pt;
 
  597   new DisplacementControlElement(controlled_element_pt,
 
  599                                  controlled_direction,
 
  606   displacement_control_load_pt();
 
  609  Displ_control_mesh_pt->add_element_pt(displ_control_el_pt); 
 
  624   new AlgebraicCollapsibleChannelMesh<ELEMENT>
 
  625   (nup, ncollapsible, ndown, ny,
 
  626    lup, lcollapsible, ldown, ly,
 
  632  add_sub_mesh(Bulk_mesh_pt);
 
  633  add_sub_mesh(Wall_mesh_pt);
 
  634  add_sub_mesh(Displ_control_mesh_pt);
 
  645  unsigned n_element=Bulk_mesh_pt->nelement();
 
  646  for(
unsigned e=0;e<n_element;e++)
 
  649    ELEMENT* el_pt = 
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
 
  660      el_pt->disable_ALE();
 
  665      bool is_in_rigid_part=
true;
 
  668      unsigned nnod=el_pt->nnode();
 
  669      for (
unsigned j=0;j<nnod;j++)
 
  671        double x=el_pt->node_pt(j)->x(0);
 
  672        if ((x>=Lup)&&(x<=(Lup+Lcollapsible)))
 
  674          is_in_rigid_part=
false;
 
  678      if (is_in_rigid_part)
 
  680        el_pt->disable_ALE();
 
  694  unsigned num_nod= bulk_mesh_pt()->nboundary_node(ibound);
 
  695  for (
unsigned inod=0;inod<num_nod;inod++)
 
  697    for(
unsigned i=0;i<2;i++)
 
  699      bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(i);
 
  704  for(ibound=2;ibound<5;ibound++)
 
  706    num_nod= bulk_mesh_pt()->nboundary_node(ibound);
 
  707    for (
unsigned inod=0;inod<num_nod;inod++)
 
  709      for(
unsigned i=0;i<2;i++)
 
  711        bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(i);
 
  718  num_nod= bulk_mesh_pt()->nboundary_node(ibound);
 
  719  for (
unsigned inod=0;inod<num_nod;inod++)
 
  721    bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
 
  727  num_nod= bulk_mesh_pt()->nboundary_node(ibound);
 
  728  for (
unsigned inod=0;inod<num_nod;inod++)
 
  730    bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(0);
 
  731    bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
 
  740  n_element = wall_mesh_pt()->nelement();
 
  741  for(
unsigned e=0;e<n_element;e++)
 
  744    FSIHermiteBeamElement *elem_pt = 
 
  745     dynamic_cast<FSIHermiteBeamElement*
>(wall_mesh_pt()->element_pt(e));
 
  758    elem_pt->undeformed_beam_pt() = undeformed_wall_pt;
 
  763    elem_pt->set_normal_pointing_out_of_fluid();
 
  785  for(
unsigned b=0;b<2;b++)
 
  788    wall_mesh_pt()->boundary_node_pt(b,0)->pin_position(0); 
 
  789    wall_mesh_pt()->boundary_node_pt(b,0)->pin_position(1);
 
  799  num_nod= bulk_mesh_pt()->nboundary_node(ibound);
 
  800  unsigned control_nod=num_nod/2;
 
  801  Left_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
 
  805  num_nod= bulk_mesh_pt()->nboundary_node(ibound);
 
  806  control_nod=num_nod/2;
 
  807  Right_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
 
  811  num_nod= wall_mesh_pt()->nnode();
 
  812  Wall_node_pt=wall_mesh_pt()->node_pt(Ncollapsible/2);
 
  825  num_nod= bulk_mesh_pt()->nboundary_node(ibound);
 
  826  for (
unsigned inod=0;inod<num_nod;inod++)
 
  828    static_cast<AlgebraicNode*
>(
 
  829     bulk_mesh_pt()->boundary_node_pt(ibound, inod))->
 
  830     set_auxiliary_node_update_fct_pt(
 
  831      FSI_functions::apply_no_slip_on_moving_wall);
 
  838  FSI_functions::setup_fluid_load_info_for_solid_elements<ELEMENT,2>
 
  839   (
this,3,Bulk_mesh_pt,Wall_mesh_pt);
 
  842  cout <<
"Total number of equations: " << assign_eqn_numbers() << std::endl; 
 
  851 template <
class ELEMENT>
 
  855                     ofstream& trace_file,
 
  856                     const double& cpu, 
const unsigned &niter)
 
  867  sprintf(filename,
"%s/soln%i.dat",Doc_info.directory().c_str(),
 
  869  some_file.open(filename);
 
  870  bulk_mesh_pt()->output(some_file,npts);
 
  874  sprintf(filename,
"%s/beam%i.dat",Doc_info.directory().c_str(),
 
  876  some_file.open(filename);
 
  877  wall_mesh_pt()->output(some_file,npts);
 
  881  sprintf(filename,
"%s/restart%i.dat",Doc_info.directory().c_str(),
 
  883  some_file.open(filename);
 
  884  some_file.precision(16);                          
 
  893  trace_file << Left_node_pt->value(0) << 
" " 
  894             << Right_node_pt->value(0) << 
" " 
  896             << Newton_iter << 
" "  
  912 template <
class ELEMENT>
 
  916                       ofstream& trace_file,
 
  918                       const unsigned &niter)
 
  929  sprintf(filename,
"%s/soln%i.dat",Doc_info.directory().c_str(),
 
  931  some_file.open(filename);
 
  932  bulk_mesh_pt()->output(some_file,npts);
 
  936  sprintf(filename,
"%s/beam%i.dat",Doc_info.directory().c_str(),
 
  938  some_file.open(filename);
 
  939  wall_mesh_pt()->output(some_file,npts);
 
  943  sprintf(filename,
"%s/restart%i.dat",Doc_info.directory().c_str(),
 
  945  some_file.open(filename);
 
  950  trace_file << time_pt()->time() << 
" ";
 
  954  Ctrl_geom_obj_pt->position(S_displ_ctrl,r);
 
  955  trace_file << r[1]  << 
" ";
 
  958  trace_file << Left_node_pt->value(0) << 
" " 
  959             << Right_node_pt->value(0) << 
" " 
  961             << Newton_iter << 
" "  
  973 template <
class ELEMENT>
 
  982    add_sub_mesh(Bulk_mesh_pt);
 
  983    add_sub_mesh(Wall_mesh_pt);
 
  984    add_sub_mesh(Displ_control_mesh_pt);
 
  985    rebuild_global_mesh();
 
  986    assign_eqn_numbers();
 
  991            << 
" # external pressure" << std::endl;
 
  994  Problem::dump(dump_file); 
 
 1001    add_sub_mesh(Bulk_mesh_pt);
 
 1002    add_sub_mesh(Wall_mesh_pt);
 
 1003    rebuild_global_mesh();
 
 1004    assign_eqn_numbers();
 
 1015 template <
class ELEMENT>
 
 1024  string input_string;
 
 1025  getline(restart_file,input_string,
'#');
 
 1026  restart_file.ignore(80,
'\n');
 
 1031     << 
"Increasing external pressure from " 
 1032     << double(atof(input_string.c_str())) << 
" to " 
 1038    std::cout << 
"Running with unchanged external pressure of "  
 1039              << double(atof(input_string.c_str())) << std::endl;
 
 1044   set_value(0,
double(atof(input_string.c_str()))+
 
 1048  Problem::read(restart_file); 
 
 1052  this->Bulk_mesh_pt->node_update();
 
 1058    add_sub_mesh(Bulk_mesh_pt);
 
 1059    add_sub_mesh(Wall_mesh_pt);
 
 1060    rebuild_global_mesh();
 
 1061    assign_eqn_numbers();
 
 1072 template <
class ELEMENT>
 
 1079    if (time_stepper_pt()->type()!=
"BDF")
 
 1081      std::ostringstream error_stream;
 
 1082      error_stream << 
"Timestepper has to be from the BDF family!\n" 
 1083                   << 
"You have specified a timestepper from the " 
 1084                   << time_stepper_pt()->type() << 
" family" << std::endl;
 
 1086      throw OomphLibError(error_stream.str(),
 
 1087                          OOMPH_CURRENT_FUNCTION,
 
 1088                        OOMPH_EXCEPTION_LOCATION);
 
 1094  ifstream* restart_file_pt=0;
 
 1104    if (restart_file_pt!=0)
 
 1107       " for restart. " << std::endl;
 
 1108      restart(*restart_file_pt);
 
 1113      std::ostringstream error_stream;
 
 1116       " for restart." << std::endl;
 
 1118      throw OomphLibError(
 
 1120       OOMPH_CURRENT_FUNCTION,
 
 1121       OOMPH_EXCEPTION_LOCATION);
 
 1130    bulk_mesh_pt()->node_update();
 
 1133    unsigned num_nod = bulk_mesh_pt()->nnode();
 
 1134    for (
unsigned n=0;n<num_nod;n++)
 
 1137      Vector<double> x(2);
 
 1138      x[0]=bulk_mesh_pt()->node_pt(n)->x(0);
 
 1139      x[1]=bulk_mesh_pt()->node_pt(n)->x(1);
 
 1142      bulk_mesh_pt()->node_pt(n)->set_value(0,6.0*(x[1]/Ly)*(1.0-(x[1]/Ly)));
 
 1143      bulk_mesh_pt()->node_pt(n)->set_value(1,0.0);
 
 1147    bulk_mesh_pt()->assign_initial_values_impulsive();
 
 1159 template <
class ELEMENT>
 
 1169  set_initial_condition();
 
 1172  Doc_info.set_directory(
"RESLT");
 
 1175  ofstream trace_file;
 
 1177  sprintf(filename,
"%s/trace.dat",Doc_info.directory().c_str());
 
 1178  trace_file.open(filename);
 
 1181  trace_file << 
"VARIABLES=\"p<sub>ext</sub>\"," 
 1182             << 
"\"y<sub>ctrl</sub>\",";
 
 1183  trace_file << 
"\"u_1\"," 
 1185             << 
"\"CPU time for solve\"," 
 1186             << 
"\"Number of Newton iterations\"," 
 1189  trace_file << 
"ZONE T=\"";
 
 1194  trace_file << std::endl;
 
 1197  doc_solution_steady(Doc_info,trace_file,0.0,0);
 
 1200  Doc_info.number()++;
 
 1224      std::cout << 
"Solving for control displ = "  
 1230      std::cout << 
"Solving for p_ext = "  
 1237    clock_t t_start = clock();
 
 1240    steady_newton_solve();
 
 1242    clock_t t_end= clock();
 
 1243    double cpu=double(t_end-t_start)/CLOCKS_PER_SEC;
 
 1248    doc_solution_steady(Doc_info,trace_file,cpu,0);
 
 1251    Doc_info.number()++;
 
 1281 template <
class ELEMENT>
 
 1295   std::cout << 
"Pressure before set initial: "  
 1300   set_initial_condition();
 
 1302   std::cout << 
"Pressure after set initial: "  
 1307   Doc_info.set_directory(
"RESLT");
 
 1310   ofstream trace_file;
 
 1312   sprintf(filename,
"%s/trace.dat",Doc_info.directory().c_str());
 
 1313   trace_file.open(filename);
 
 1317  trace_file << 
"VARIABLES=\"time\"," 
 1318             << 
"\"y<sub>ctrl</sub>\",";
 
 1319  trace_file << 
"\"u_1\"," 
 1321             << 
"\"CPU time for solve\"," 
 1322             << 
"\"Number of Newton iterations\"" 
 1325   trace_file << 
"ZONE T=\"";
 
 1330   trace_file << std::endl;
 
 1333   doc_solution_unsteady(Doc_info,trace_file,0.0,0);
 
 1336   Doc_info.number()++;
 
 1345     clock_t t_start = clock();
 
 1348     unsteady_newton_solve(dt);
 
 1350     clock_t t_end= clock();
 
 1351     double cpu=double(t_end-t_start)/CLOCKS_PER_SEC;
 
 1356     doc_solution_unsteady(Doc_info,trace_file,cpu,0);
 
 1359     Doc_info.number()++;
 
OneDLagrangianMesh< FSIHermiteBeamElement > * Wall_mesh_pt
Pointer to the "wall" mesh.
 
double Ldown
x-length in the downstream part of the channel
 
GeomObject * Ctrl_geom_obj_pt
Pointer to GeomObject at which displacement control is applied (or at which wall displacement is moni...
 
MeshAsGeomObject * Wall_geom_object_pt
Pointer to geometric object (one Lagrangian, two Eulerian coordinates) that will be built from the wa...
 
Vector< double > S_displ_ctrl
Vector of local coordinates of displacement control point in Ctrl_geom_obj_pt.
 
unsigned Nup
Number of elements in the x direction in the upstream part of the channel.
 
virtual void steady_run()
Steady run; virtual so it can be overloaded in derived problem classes.
 
void dump_it(ofstream &dump_file)
Dump problem to disk to allow for restart.
 
void restart(ifstream &restart_file)
Read problem for restart from specified restart file.
 
DocInfo Doc_info
DocInfo object.
 
Node * Wall_node_pt
Pointer to control node on the wall.
 
unsigned Ncollapsible
Number of elements in the x direction in the collapsible part of the channel.
 
void actions_after_newton_solve()
Update the problem after solve (empty)
 
Node * Left_node_pt
Pointer to the left control node.
 
unsigned Ny
Number of elements across the channel.
 
Node * Right_node_pt
Pointer to right control node.
 
unsigned Ndown
Number of elements in the x direction in the downstream part of the channel.
 
virtual void doc_solution_steady(DocInfo &doc_info, ofstream &trace_file, const double &cpu, const unsigned &niter)
Doc the steady solution.
 
unsigned Newton_iter
Counter for Newton iterations.
 
AlgebraicCollapsibleChannelMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the "bulk" mesh.
 
FSICollapsibleChannelProblem(const unsigned &nup, const unsigned &ncollapsible, const unsigned &ndown, const unsigned &ny, const double &lup, const double &lcollapsible, const double &ldown, const double &ly, const bool &displ_control, const bool &steady_flag)
Constructor: The arguments are the number of elements and the lengths of the domain.
 
double Lup
x-length in the upstream part of the channel
 
bool Steady_flag
Flag for steady run.
 
AlgebraicCollapsibleChannelMesh< ELEMENT > * bulk_mesh_pt()
Access function for the specific bulk (fluid) mesh.
 
virtual void doc_solution_unsteady(DocInfo &doc_info, ofstream &trace_file, const double &cpu, const unsigned &niter)
Doc the unsteady solution.
 
~FSICollapsibleChannelProblem()
Destructor.
 
void actions_before_newton_convergence_check()
Update before checking Newton convergence: Update the nodal positions in the fluid mesh in response t...
 
Mesh * Displ_control_mesh_pt
Pointer to the mesh that contains the displacement control element.
 
void actions_before_newton_solve()
Actions before solve. Reset counter for number of Newton iterations.
 
double Ly
Transverse length.
 
virtual void unsteady_run(const double &dt=0.1)
Unsteady run; virtual so it can be overloaded in derived problem classes. Specify timestep or use def...
 
double Lcollapsible
x-length in the collapsible part of the channel
 
OneDLagrangianMesh< FSIHermiteBeamElement > * wall_mesh_pt()
Access function for the wall mesh.
 
bool Displ_control
Use displacement control?
 
void set_initial_condition()
Apply initial conditions.
 
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
 
double squash_fct(const double &s)
Mapping [0,1] -> [0,1] that re-distributes nodal points across the channel width.
 
double Delta
Boundary layer width.
 
double Fract_in_BL
Fraction of points in boundary layer.
 
Extend namespace for control flags.
 
string Restart_file_name
Name of restart file.
 
string Run_identifier_string
String to identify the run type in trace file.
 
unsigned Resolution_factor
Resolution factor (multiplier for number of elements across channel)
 
unsigned Nsteps
Number of steps in parameter study.
 
unsigned Steady_flag
Steady run (1) or unsteady run (0)
 
void doc_flags()
Doc flags.
 
unsigned Use_displ_control
Use displacement control (1) or not (0)
 
Namespace for phyical parameters.
 
double ReSt
Womersley = Reynolds times Strouhal.
 
void load(const Vector< double > &xi, const Vector< double > &x, const Vector< double > &N, Vector< double > &load)
Load function: Apply a constant external pressure to the wall. Note: This is the load without the flu...
 
double Pmax
Max. pressure. Only used in steady runs during parameter incrementation. Use 2.0 for Re=250; 3....
 
double Sigma0
2nd Piola Kirchhoff pre-stress. As in Heil (2004) paper.
 
double Q
Fluid structure interaction parameter: Ratio of stresses used for non-dimensionalisation of fluid to ...
 
double P_step
Jump in pressure after a restart – used to give a steady solution a kick before starting a time-depen...
 
double Re
Reynolds number.
 
Data * P_ext_data_pt
Pointer to Data object that stores external pressure.
 
double Yprescr_min
Min. of prescribed vertical position of conrol point (only used during parameter study with displacem...
 
double Pmin
Min. pressure. Only used in steady runs during parameter incrementation. Use 1.5 for values of Re to ...
 
double H
Non-dimensional wall thickness. As in Heil (2004) paper.
 
double Yprescr
Current prescribed vertical position of control point (only used for displacement control)