80 void load(
const Vector<double>& xi,
const Vector<double>& x,
81 const Vector<double>& N, Vector<double>&
load)
83 for(
unsigned i=0;i<2;i++)
85 load[i] = -P_ext_data_pt->value(0)*N[i];
126 if (s<0.5*Fract_in_BL)
130 else if (s>1.0-0.5*Fract_in_BL)
132 y=2.0*Delta/Fract_in_BL*s+1.0-2.0*Delta/
Fract_in_BL;
136 y=(1.0-2.0*
Delta)/(1.0-Fract_in_BL)*s+
174 void position(
const Vector<double>& zeta, Vector<double>& r)
const 185 void position(
const unsigned& t,
const Vector<double>& zeta,
186 Vector<double>& r)
const 201 DenseMatrix<double> &drdzeta,
202 RankThreeTensor<double> &ddrdzeta)
const 261 std::cout <<
"\nFlags:\n" 264 std::cout <<
"-- Resolution factor: " << Resolution_factor << std::endl;
268 std::cout <<
"-- Steady run " << std::endl;
269 if (Use_displ_control)
271 std::cout <<
"-- Using displacement control " << std::endl;
275 std::cout <<
"-- Not using displacement control " << std::endl;
280 std::cout <<
"-- Unsteady run " << std::endl;
281 if (Use_displ_control)
283 std::cout <<
"-- Not using displacement control (command line flag\n" 284 <<
" overwritten because it's an unsteady run!) " 289 std::cout <<
"-- Reynolds number: " 292 std::cout <<
"-- FSI parameter Q: " 296 if (Restart_file_name!=
"")
298 std::cout <<
"-- Performing restart from: " << Restart_file_name
305 std::cout <<
"-- No restart " << std::endl;
307 std::cout << std::endl;
317 template <
class ELEMENT>
326 const unsigned& ncollapsible,
327 const unsigned& ndown,
330 const double& lcollapsible,
333 const bool& displ_control,
334 const bool& steady_flag);
344 virtual void steady_run();
348 virtual void unsteady_run(
const double& dt=0.1);
356 AlgebraicCollapsibleChannelMesh<ELEMENT>*
> 384 Bulk_mesh_pt->node_update();
392 virtual void doc_solution_steady(DocInfo& doc_info, ofstream& trace_file,
393 const double& cpu,
const unsigned &niter);
396 virtual void doc_solution_unsteady(DocInfo& doc_info, ofstream& trace_file,
397 const double& cpu,
const unsigned &niter);
400 void set_initial_condition();
406 void dump_it(ofstream& dump_file);
409 void restart(ifstream& restart_file);
486 template <
class ELEMENT>
489 const unsigned& ncollapsible,
490 const unsigned& ndown,
493 const double& lcollapsible,
496 const bool& displ_control,
497 const bool& steady_flag)
506 Ncollapsible=ncollapsible;
510 Lcollapsible=lcollapsible;
518 Displ_control=displ_control;
525 std::cout <<
"Switched off displacement control for unsteady run!" 532 Problem::Max_residuals=1000.0;
540 add_time_stepper_pt(
new BDF<2>);
543 Steady<2>* wall_time_stepper_pt =
new Steady<2>;
546 add_time_stepper_pt(wall_time_stepper_pt);
553 Wall_mesh_pt =
new OneDLagrangianMesh<FSIHermiteBeamElement>
554 (Ncollapsible,Lcollapsible,undeformed_wall_pt,wall_time_stepper_pt);
559 new MeshAsGeomObject(Wall_mesh_pt);
564 Vector<double> zeta_displ_ctrl(1);
565 zeta_displ_ctrl[0]=3.5;
568 zeta_displ_ctrl[0]=3.0;
573 zeta_displ_ctrl[0]=2.5;
575 std::cout <<
"Wall control point located at zeta=" <<zeta_displ_ctrl[0]
577 S_displ_ctrl.resize(1);
580 Wall_geom_object_pt->locate_zeta(zeta_displ_ctrl,
587 Displ_control_mesh_pt=
new Mesh;
590 SolidFiniteElement* controlled_element_pt=
591 dynamic_cast<SolidFiniteElement*
>(Ctrl_geom_obj_pt);
594 unsigned controlled_direction=1;
597 DisplacementControlElement* displ_control_el_pt;
601 new DisplacementControlElement(controlled_element_pt,
603 controlled_direction,
610 displacement_control_load_pt();
613 Displ_control_mesh_pt->add_element_pt(displ_control_el_pt);
628 new AlgebraicCollapsibleChannelMesh<ELEMENT>
629 (nup, ncollapsible, ndown, ny,
630 lup, lcollapsible, ldown, ly,
636 add_sub_mesh(Bulk_mesh_pt);
637 add_sub_mesh(Wall_mesh_pt);
638 add_sub_mesh(Displ_control_mesh_pt);
649 unsigned n_element=Bulk_mesh_pt->nelement();
650 for(
unsigned e=0;e<n_element;e++)
653 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
664 el_pt->disable_ALE();
669 bool is_in_rigid_part=
true;
672 unsigned nnod=el_pt->nnode();
673 for (
unsigned j=0;j<nnod;j++)
675 double x=el_pt->node_pt(j)->x(0);
676 if ((x>=Lup)&&(x<=(Lup+Lcollapsible)))
678 is_in_rigid_part=
false;
682 if (is_in_rigid_part)
684 el_pt->disable_ALE();
698 unsigned num_nod= bulk_mesh_pt()->nboundary_node(ibound);
699 for (
unsigned inod=0;inod<num_nod;inod++)
701 for(
unsigned i=0;i<2;i++)
703 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(i);
708 for(ibound=2;ibound<5;ibound++)
710 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
711 for (
unsigned inod=0;inod<num_nod;inod++)
713 for(
unsigned i=0;i<2;i++)
715 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(i);
722 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
723 for (
unsigned inod=0;inod<num_nod;inod++)
725 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
731 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
732 for (
unsigned inod=0;inod<num_nod;inod++)
734 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(0);
735 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
744 n_element = wall_mesh_pt()->nelement();
745 for(
unsigned e=0;e<n_element;e++)
748 FSIHermiteBeamElement *elem_pt =
749 dynamic_cast<FSIHermiteBeamElement*
>(wall_mesh_pt()->element_pt(e));
762 elem_pt->undeformed_beam_pt() = undeformed_wall_pt;
767 elem_pt->set_normal_pointing_out_of_fluid();
789 for(
unsigned b=0;b<2;b++)
792 wall_mesh_pt()->boundary_node_pt(b,0)->pin_position(0);
793 wall_mesh_pt()->boundary_node_pt(b,0)->pin_position(1);
803 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
804 unsigned control_nod=num_nod/2;
805 Left_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
809 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
810 control_nod=num_nod/2;
811 Right_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
815 num_nod= wall_mesh_pt()->nnode();
816 Wall_node_pt=wall_mesh_pt()->node_pt(Ncollapsible/2);
829 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
830 for (
unsigned inod=0;inod<num_nod;inod++)
832 static_cast<AlgebraicNode*
>(
833 bulk_mesh_pt()->boundary_node_pt(ibound, inod))->
834 set_auxiliary_node_update_fct_pt(
835 FSI_functions::apply_no_slip_on_moving_wall);
842 FSI_functions::setup_fluid_load_info_for_solid_elements<ELEMENT,2>
843 (
this,3,Bulk_mesh_pt,Wall_mesh_pt);
846 cout <<
"Total number of equations: " << assign_eqn_numbers() << std::endl;
855 template <
class ELEMENT>
859 ofstream& trace_file,
860 const double& cpu,
const unsigned &niter)
871 sprintf(filename,
"%s/soln%i.dat",Doc_info.directory().c_str(),
873 some_file.open(filename);
874 bulk_mesh_pt()->output(some_file,npts);
878 sprintf(filename,
"%s/beam%i.dat",Doc_info.directory().c_str(),
880 some_file.open(filename);
881 wall_mesh_pt()->output(some_file,npts);
885 sprintf(filename,
"%s/restart%i.dat",Doc_info.directory().c_str(),
887 some_file.open(filename);
888 some_file.precision(16);
897 trace_file << Left_node_pt->value(0) <<
" " 898 << Right_node_pt->value(0) <<
" " 900 << Newton_iter <<
" " 916 template <
class ELEMENT>
920 ofstream& trace_file,
922 const unsigned &niter)
933 sprintf(filename,
"%s/soln%i.dat",Doc_info.directory().c_str(),
935 some_file.open(filename);
936 bulk_mesh_pt()->output(some_file,npts);
940 sprintf(filename,
"%s/beam%i.dat",Doc_info.directory().c_str(),
942 some_file.open(filename);
943 wall_mesh_pt()->output(some_file,npts);
947 sprintf(filename,
"%s/restart%i.dat",Doc_info.directory().c_str(),
949 some_file.open(filename);
954 trace_file << time_pt()->time() <<
" ";
958 Ctrl_geom_obj_pt->position(S_displ_ctrl,r);
959 trace_file << r[1] <<
" ";
962 trace_file << Left_node_pt->value(0) <<
" " 963 << Right_node_pt->value(0) <<
" " 965 << Newton_iter <<
" " 977 template <
class ELEMENT>
986 add_sub_mesh(Bulk_mesh_pt);
987 add_sub_mesh(Wall_mesh_pt);
988 add_sub_mesh(Displ_control_mesh_pt);
989 rebuild_global_mesh();
990 assign_eqn_numbers();
995 <<
" # external pressure" << std::endl;
998 Problem::dump(dump_file);
1005 add_sub_mesh(Bulk_mesh_pt);
1006 add_sub_mesh(Wall_mesh_pt);
1007 rebuild_global_mesh();
1008 assign_eqn_numbers();
1019 template <
class ELEMENT>
1028 string input_string;
1029 getline(restart_file,input_string,
'#');
1030 restart_file.ignore(80,
'\n');
1035 <<
"Increasing external pressure from " 1036 << double(atof(input_string.c_str())) <<
" to " 1042 std::cout <<
"Running with unchanged external pressure of " 1043 << double(atof(input_string.c_str())) << std::endl;
1048 set_value(0,
double(atof(input_string.c_str()))+
1052 Problem::read(restart_file);
1056 this->Bulk_mesh_pt->node_update();
1062 add_sub_mesh(Bulk_mesh_pt);
1063 add_sub_mesh(Wall_mesh_pt);
1064 rebuild_global_mesh();
1065 assign_eqn_numbers();
1076 template <
class ELEMENT>
1083 if (time_stepper_pt()->type()!=
"BDF")
1085 std::ostringstream error_stream;
1086 error_stream <<
"Timestepper has to be from the BDF family!\n" 1087 <<
"You have specified a timestepper from the " 1088 << time_stepper_pt()->type() <<
" family" << std::endl;
1090 throw OomphLibError(error_stream.str(),
1091 OOMPH_CURRENT_FUNCTION,
1092 OOMPH_EXCEPTION_LOCATION);
1098 ifstream* restart_file_pt=0;
1108 if (restart_file_pt!=0)
1111 " for restart. " << std::endl;
1112 restart(*restart_file_pt);
1117 std::ostringstream error_stream;
1120 " for restart." << std::endl;
1122 throw OomphLibError(
1124 OOMPH_CURRENT_FUNCTION,
1125 OOMPH_EXCEPTION_LOCATION);
1134 bulk_mesh_pt()->node_update();
1137 unsigned num_nod = bulk_mesh_pt()->nnode();
1138 for (
unsigned n=0;n<num_nod;n++)
1141 Vector<double> x(2);
1142 x[0]=bulk_mesh_pt()->node_pt(n)->x(0);
1143 x[1]=bulk_mesh_pt()->node_pt(n)->x(1);
1146 bulk_mesh_pt()->node_pt(n)->set_value(0,6.0*(x[1]/Ly)*(1.0-(x[1]/Ly)));
1147 bulk_mesh_pt()->node_pt(n)->set_value(1,0.0);
1151 bulk_mesh_pt()->assign_initial_values_impulsive();
1163 template <
class ELEMENT>
1173 set_initial_condition();
1176 Doc_info.set_directory(
"RESLT");
1179 ofstream trace_file;
1181 sprintf(filename,
"%s/trace.dat",Doc_info.directory().c_str());
1182 trace_file.open(filename);
1185 trace_file <<
"VARIABLES=\"p<sub>ext</sub>\"," 1186 <<
"\"y<sub>ctrl</sub>\",";
1187 trace_file <<
"\"u_1\"," 1189 <<
"\"CPU time for solve\"," 1190 <<
"\"Number of Newton iterations\"," 1193 trace_file <<
"ZONE T=\"";
1198 trace_file << std::endl;
1201 doc_solution_steady(Doc_info,trace_file,0.0,0);
1204 Doc_info.number()++;
1228 std::cout <<
"Solving for control displ = " 1234 std::cout <<
"Solving for p_ext = " 1241 clock_t t_start = clock();
1244 steady_newton_solve();
1246 clock_t t_end= clock();
1247 double cpu=double(t_end-t_start)/CLOCKS_PER_SEC;
1252 doc_solution_steady(Doc_info,trace_file,cpu,0);
1255 Doc_info.number()++;
1285 template <
class ELEMENT>
1299 std::cout <<
"Pressure before set initial: " 1304 set_initial_condition();
1306 std::cout <<
"Pressure after set initial: " 1311 Doc_info.set_directory(
"RESLT");
1314 ofstream trace_file;
1316 sprintf(filename,
"%s/trace.dat",Doc_info.directory().c_str());
1317 trace_file.open(filename);
1321 trace_file <<
"VARIABLES=\"time\"," 1322 <<
"\"y<sub>ctrl</sub>\",";
1323 trace_file <<
"\"u_1\"," 1325 <<
"\"CPU time for solve\"," 1326 <<
"\"Number of Newton iterations\"" 1329 trace_file <<
"ZONE T=\"";
1334 trace_file << std::endl;
1337 doc_solution_unsteady(Doc_info,trace_file,0.0,0);
1340 Doc_info.number()++;
1349 clock_t t_start = clock();
1352 unsteady_newton_solve(dt);
1354 clock_t t_end= clock();
1355 double cpu=double(t_end-t_start)/CLOCKS_PER_SEC;
1360 doc_solution_unsteady(Doc_info,trace_file,cpu,0);
1363 Doc_info.number()++;
string Run_identifier_string
String to identify the run type in trace file.
Extend namespace for control flags.
unsigned Nsteps
Number of steps in parameter study.
void actions_before_newton_convergence_check()
Update before checking Newton convergence: Update the nodal positions in the fluid mesh in response t...
OneDLagrangianMesh< FSIHermiteBeamElement > * wall_mesh_pt()
Access function for the wall mesh.
void actions_before_newton_solve()
Actions before solve. Reset counter for number of Newton iterations.
~FSICollapsibleChannelProblem()
Destructor.
DocInfo Doc_info
DocInfo object.
AlgebraicCollapsibleChannelMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the "bulk" mesh.
double Yprescr
Current prescribed vertical position of control point (only used for displacement control) ...
double Ly
Transverse length.
void set_initial_condition()
Apply initial conditions.
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...
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.
unsigned Steady_flag
Steady run (1) or unsteady run (0)
double Pmax
Max. pressure. Only used in steady runs during parameter incrementation. Use 2.0 for Re=250; 3...
AlgebraicCollapsibleChannelMesh< ELEMENT > * bulk_mesh_pt()
Access function for the specific bulk (fluid) mesh.
void restart(ifstream &restart_file)
Read problem for restart from specified restart file.
void doc_flags()
Doc flags.
OneDLagrangianMesh< FSIHermiteBeamElement > * Wall_mesh_pt
Pointer to the "wall" mesh.
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 ...
Node * Wall_node_pt
Pointer to control node on the wall.
unsigned Nup
Number of elements in the x direction in the upstream part of the channel.
MeshAsGeomObject * Wall_geom_object_pt
Pointer to geometric object (one Lagrangian, two Eulerian coordinates) that will be built from the wa...
unsigned Newton_iter
Counter for Newton iterations.
double Pmin
Min. pressure. Only used in steady runs during parameter incrementation. Use 1.5 for values of Re to ...
unsigned Resolution_factor
Resolution factor (multiplier for number of elements across channel)
double Lcollapsible
x-length in the collapsible part of the channel
double ReSt
Womersley = Reynolds times Strouhal.
unsigned Ncollapsible
Number of elements in the x direction in the collapsible part of the channel.
Data * P_ext_data_pt
Pointer to Data object that stores external pressure.
virtual void doc_solution_steady(DocInfo &doc_info, ofstream &trace_file, const double &cpu, const unsigned &niter)
Doc the steady solution.
double Delta
Boundary layer width.
void dump_it(ofstream &dump_file)
Dump problem to disk to allow for restart.
double Re
Reynolds number.
void actions_after_newton_solve()
Update the problem after solve (empty)
GeomObject * Ctrl_geom_obj_pt
double Fract_in_BL
Fraction of points in boundary layer.
Node * Left_node_pt
Pointer to the left control node.
bool Steady_flag
Flag for steady run.
Namespace for phyical parameters.
double H
Non-dimensional wall thickness. As in Heil (2004) paper.
virtual void doc_solution_unsteady(DocInfo &doc_info, ofstream &trace_file, const double &cpu, const unsigned &niter)
Doc the unsteady solution.
Mesh * Displ_control_mesh_pt
Pointer to the mesh that contains the displacement control element.
unsigned Use_displ_control
Use displacement control (1) or not (0)
Node * Right_node_pt
Pointer to right control node.
double Ldown
x-length in the downstream part of the channel
string Restart_file_name
Name of restart file.
Vector< double > S_displ_ctrl
Vector of local coordinates of displacement control point in Ctrl_geom_obj_pt.
double Lup
x-length in the upstream part of the channel
virtual void steady_run()
Steady run.
bool Displ_control
Use displacement control?
double P_step
Jump in pressure after a restart – used to give a steady solution a kick before starting a time-depe...
double squash_fct(const double &s)
Mapping [0,1] -> [0,1] that re-distributes nodal points across the channel width. ...
unsigned Ndown
Number of elements in the x direction in the downstream part of the channel.
unsigned Ny
Number of elements across the channel.
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...