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)