33 #include "navier_stokes.h" 36 #include "constitutive.h" 39 #include "meshes/one_d_lagrangian_mesh.h" 42 #include "meshes/collapsible_channel_mesh.h" 46 using namespace oomph;
52 template <
class ELEMENT>
54 public virtual CollapsibleChannelMesh<ELEMENT>,
55 public virtual SolidMesh
64 const unsigned& ncollapsible,
65 const unsigned& ndown,
68 const double& lcollapsible,
72 TimeStepper* time_stepper_pt=
73 &Mesh::Default_TimeStepper) :
74 CollapsibleChannelMesh<ELEMENT>(nup, ncollapsible, ndown, ny,
75 lup, lcollapsible, ldown, ly,
82 set_lagrangian_nodal_coordinates();
109 if (s<0.5*Fract_in_BL)
113 else if (s>1.0-0.5*Fract_in_BL)
115 y=2.0*Delta/Fract_in_BL*s+1.0-2.0*Delta/
Fract_in_BL;
119 y=(1.0-2.0*
Delta)/(1.0-Fract_in_BL)*s+
154 void position(
const Vector<double>& zeta, Vector<double>& r)
const 165 void position(
const unsigned& t,
const Vector<double>& zeta,
166 Vector<double>& r)
const 181 DenseMatrix<double> &drdzeta,
182 RankThreeTensor<double> &ddrdzeta)
const 236 const Vector<double>& x,
237 const Vector<double>& n,
238 Vector<double>& traction)
258 void load(
const Vector<double>& xi,
const Vector<double>& x,
259 const Vector<double>& N, Vector<double>&
load)
261 for(
unsigned i=0;i<2;i++)
263 load[i] = -P_ext*N[i];
281 template <
class ELEMENT>
290 const unsigned& ncollapsible,
291 const unsigned& ndown,
294 const double& lcollapsible,
332 unsigned num_nod=bulk_mesh_pt()->nboundary_node(ibound);
333 for (
unsigned inod=0;inod<num_nod;inod++)
336 Node* node_pt=bulk_mesh_pt()->boundary_node_pt(ibound,inod);
339 FSI_functions::apply_no_slip_on_moving_wall(node_pt);
345 void doc_solution(DocInfo& doc_info,ofstream& trace_file);
348 void set_initial_condition();
353 void create_traction_elements(
const unsigned &b,
354 Mesh*
const &bulk_mesh_pt,
355 Mesh*
const &traction_mesh_pt);
358 void delete_traction_elements(Mesh*
const &traction_mesh_pt);
362 void create_lagrange_multiplier_elements();
366 void delete_lagrange_multiplier_elements();
373 unsigned Ncollapsible;
398 Mesh* Applied_fluid_traction_mesh_pt;
404 OneDLagrangianMesh<FSIHermiteBeamElement>* Wall_mesh_pt;
430 template <
class ELEMENT>
433 const unsigned& ncollapsible,
434 const unsigned& ndown,
437 const double& lcollapsible,
443 Ncollapsible=ncollapsible;
447 Lcollapsible=lcollapsible;
453 Problem::Max_residuals=1000.0;
456 BDF<2>* fluid_time_stepper_pt=
new BDF<2>;
459 add_time_stepper_pt(fluid_time_stepper_pt);
462 Steady<2>* wall_time_stepper_pt =
new Steady<2>;
465 add_time_stepper_pt(wall_time_stepper_pt);
473 Wall_mesh_pt =
new OneDLagrangianMesh<FSIHermiteBeamElement>
474 (Ncollapsible,Lcollapsible,undeformed_wall_pt,wall_time_stepper_pt);
479 new MeshAsGeomObject(Wall_mesh_pt);
486 (nup, ncollapsible, ndown, ny,
487 lup, lcollapsible, ldown, ly,
489 fluid_time_stepper_pt);
495 bool update_all_solid_nodes=
true;
496 Bulk_mesh_pt->node_update(update_all_solid_nodes);
497 Bulk_mesh_pt->set_lagrangian_nodal_coordinates();
502 Applied_fluid_traction_mesh_pt =
new Mesh;
506 create_traction_elements(5,Bulk_mesh_pt,Applied_fluid_traction_mesh_pt);
510 Lagrange_multiplier_mesh_pt=
new SolidMesh;
511 create_lagrange_multiplier_elements();
514 add_sub_mesh(Bulk_mesh_pt);
515 add_sub_mesh(Applied_fluid_traction_mesh_pt);
516 add_sub_mesh(Wall_mesh_pt);
517 add_sub_mesh(Lagrange_multiplier_mesh_pt);
530 unsigned n_element=Bulk_mesh_pt->nelement();
531 for(
unsigned e=0;e<n_element;e++)
535 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
544 el_pt->constitutive_law_pt() = Constitutive_law_pt;
559 unsigned num_nod= bulk_mesh_pt()->nboundary_node(ibound);
560 for (
unsigned inod=0;inod<num_nod;inod++)
562 for(
unsigned i=0;i<2;i++)
564 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(i);
569 for(ibound=2;ibound<5;ibound++)
571 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
572 for (
unsigned inod=0;inod<num_nod;inod++)
574 for(
unsigned i=0;i<2;i++)
576 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(i);
583 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
584 for (
unsigned inod=0;inod<num_nod;inod++)
586 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
592 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
593 for (
unsigned inod=0;inod<num_nod;inod++)
596 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
602 for (
unsigned ibound=0;ibound<6;ibound++)
606 unsigned num_nod= bulk_mesh_pt()->nboundary_node(ibound);
607 for (
unsigned inod=0;inod<num_nod;inod++)
609 for(
unsigned i=0;i<2;i++)
611 dynamic_cast<SolidNode*
>(bulk_mesh_pt()->
612 boundary_node_pt(ibound, inod))
620 unsigned nnod=bulk_mesh_pt()->nnode();
621 for (
unsigned j=0;j<nnod;j++)
623 SolidNode* nod_pt=
dynamic_cast<SolidNode*
>(bulk_mesh_pt()->node_pt(j));
624 if ((nod_pt->x(0)<=lup)||(nod_pt->x(0)>=(lup+lcollapsible)))
626 for(
unsigned i=0;i<2;i++)
628 nod_pt->pin_position(i);
639 unsigned n_el=Applied_fluid_traction_mesh_pt->nelement();
640 for(
unsigned e=0;e<n_el;e++)
643 NavierStokesTractionElement<ELEMENT> *el_pt =
644 dynamic_cast< NavierStokesTractionElement<ELEMENT>*
>(
645 Applied_fluid_traction_mesh_pt->element_pt(e));
659 n_element = wall_mesh_pt()->nelement();
660 for(
unsigned e=0;e<n_element;e++)
663 FSIHermiteBeamElement *elem_pt =
664 dynamic_cast<FSIHermiteBeamElement*
>(wall_mesh_pt()->element_pt(e));
677 elem_pt->undeformed_beam_pt() = undeformed_wall_pt;
682 elem_pt->set_normal_pointing_out_of_fluid();
693 for(
unsigned b=0;b<2;b++)
696 wall_mesh_pt()->boundary_node_pt(b,0)->pin_position(0);
697 wall_mesh_pt()->boundary_node_pt(b,0)->pin_position(1);
707 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
708 unsigned control_nod=num_nod/2;
709 Left_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
713 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
714 control_nod=num_nod/2;
715 Right_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
719 num_nod= wall_mesh_pt()->nnode();
720 Wall_node_pt=wall_mesh_pt()->node_pt(Ncollapsible/2);
733 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
734 for (
unsigned inod=0;inod<num_nod;inod++)
736 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->
737 set_auxiliary_node_update_fct_pt(
738 FSI_functions::apply_no_slip_on_moving_wall);
745 FSI_functions::setup_fluid_load_info_for_solid_elements<ELEMENT,2>
746 (
this,3,Bulk_mesh_pt,Wall_mesh_pt);
749 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
760 template <
class ELEMENT>
762 ofstream& trace_file)
772 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
774 some_file.open(filename);
775 bulk_mesh_pt()->output(some_file,npts);
779 sprintf(filename,
"%s/beam%i.dat",doc_info.directory().c_str(),
781 some_file.open(filename);
782 wall_mesh_pt()->output(some_file,npts);
788 unsigned nsteps=time_stepper_pt(1)->nprev_values();
789 for (
unsigned t=0;t<=nsteps;t++)
791 sprintf(filename,
"%s/wall%i-%i.dat",doc_info.directory().c_str(),
792 doc_info.number(),t);
793 some_file.open(filename);
794 unsigned n_elem=wall_mesh_pt()->nelement();
795 for (
unsigned ielem=0;ielem<n_elem;ielem++)
797 dynamic_cast<FSIHermiteBeamElement*
>(wall_mesh_pt()->element_pt(ielem))->
798 output(t,some_file,npts);
806 trace_file << time_pt()->time() <<
" " 807 << Wall_node_pt->x(1) <<
" " 808 << Left_node_pt->value(0) <<
" " 809 << Right_node_pt->value(0) <<
" " 822 template <
class ELEMENT>
824 const unsigned &b, Mesh*
const &bulk_mesh_pt, Mesh*
const &traction_mesh_pt)
828 unsigned n_element = bulk_mesh_pt->nboundary_element(b);
831 for(
unsigned e=0;e<n_element;e++)
834 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
> 835 (bulk_mesh_pt->boundary_element_pt(b,e));
838 int face_index = bulk_mesh_pt->face_index_at_boundary(b,e);
841 NavierStokesTractionElement<ELEMENT>* flux_element_pt =
842 new NavierStokesTractionElement<ELEMENT>(bulk_elem_pt,face_index);
845 traction_mesh_pt->add_element_pt(flux_element_pt);
856 template<
class ELEMENT>
861 unsigned n_element = surface_mesh_pt->nelement();
864 for(
unsigned e=0;e<n_element;e++)
867 delete surface_mesh_pt->element_pt(e);
871 surface_mesh_pt->flush_element_and_node_storage();
879 template<
class ELEMENT>
887 unsigned n_element = bulk_mesh_pt()->nboundary_element(b);
890 for(
unsigned e=0;e<n_element;e++)
893 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(
894 bulk_mesh_pt()->boundary_element_pt(b,e));
897 int face_index = bulk_mesh_pt()->face_index_at_boundary(b,e);
900 Lagrange_multiplier_mesh_pt->add_element_pt(
901 new ImposeDisplacementByLagrangeMultiplierElement<ELEMENT>(
902 bulk_elem_pt,face_index));
908 n_element=Lagrange_multiplier_mesh_pt->nelement();
909 for(
unsigned i=0;i<n_element;i++)
912 ImposeDisplacementByLagrangeMultiplierElement<ELEMENT> *el_pt =
913 dynamic_cast<ImposeDisplacementByLagrangeMultiplierElement<ELEMENT>*
> 914 (Lagrange_multiplier_mesh_pt->element_pt(i));
919 el_pt->set_boundary_shape_geom_object_pt(Wall_geom_object_pt,b);
922 unsigned nnod=el_pt->nnode();
923 for (
unsigned j=0;j<nnod;j++)
925 Node* nod_pt = el_pt->node_pt(j);
928 if ((nod_pt->is_on_boundary(2))||(nod_pt->is_on_boundary(4)))
932 unsigned n_bulk_value=el_pt->nbulk_value(j);
935 unsigned nval=nod_pt->nvalue();
936 for (
unsigned j=n_bulk_value;j<nval;j++)
953 template<
class ELEMENT>
958 unsigned n_element = Lagrange_multiplier_mesh_pt->nelement();
961 for(
unsigned e=0;e<n_element;e++)
964 delete Lagrange_multiplier_mesh_pt->element_pt(e);
968 Lagrange_multiplier_mesh_pt->flush_element_and_node_storage();
977 template <
class ELEMENT>
981 if (time_stepper_pt()->type()!=
"BDF")
983 std::ostringstream error_stream;
984 error_stream <<
"Timestepper has to be from the BDF family!\n" 985 <<
"You have specified a timestepper from the " 986 << time_stepper_pt()->type() <<
" family" << std::endl;
988 throw OomphLibError(error_stream.str(),
989 OOMPH_CURRENT_FUNCTION,
990 OOMPH_EXCEPTION_LOCATION);
994 unsigned num_nod = bulk_mesh_pt()->nnode();
995 for (
unsigned n=0;n<num_nod;n++)
999 x[0]=bulk_mesh_pt()->node_pt(n)->x(0);
1000 x[1]=bulk_mesh_pt()->node_pt(n)->x(1);
1003 bulk_mesh_pt()->node_pt(n)->set_value(0,6.0*(x[1]/Ly)*(1.0-(x[1]/Ly)));
1004 bulk_mesh_pt()->node_pt(n)->set_value(1,0.0);
1008 bulk_mesh_pt()->assign_initial_values_impulsive();
1009 wall_mesh_pt()->assign_initial_values_impulsive();
1025 CommandLineArgs::setup(argc,argv);
1028 unsigned coarsening_factor=4;
1029 if (CommandLineArgs::Argc>1)
1031 coarsening_factor=4;
1035 unsigned nup=20/coarsening_factor;
1036 unsigned ncollapsible=40/coarsening_factor;
1037 unsigned ndown=40/coarsening_factor;
1038 unsigned ny=16/coarsening_factor;
1042 double lcollapsible=10.0;
1058 <PseudoSolidNodeUpdateElement<
1059 QTaylorHoodElement<2>,
1060 QPVDElement<2,3> > >
1061 problem(nup, ncollapsible, ndown, ny,
1062 lup, lcollapsible, ldown, ly);
1068 <PseudoSolidNodeUpdateElement<
1069 QCrouzeixRaviartElement<2>,
1070 QPVDElement<2,3> > >
1071 problem(nup, ncollapsible, ndown, ny,
1072 lup, lcollapsible, ldown, ly);
1087 problem.time_pt()->time()=t_min;
1088 problem.initialise_dt(dt);
1091 problem.set_initial_condition();
1095 doc_info.set_directory(
"RESLT");
1098 ofstream trace_file;
1100 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
1101 trace_file.open(filename);
1104 problem.doc_solution(doc_info, trace_file);
1107 doc_info.number()++;
1110 unsigned nstep = unsigned((t_max-t_min)/dt);
1111 if (CommandLineArgs::Argc>1)
1117 for (
unsigned istep=0;istep<nstep;istep++)
1120 problem.unsteady_newton_solve(dt);
1123 problem.doc_solution(doc_info, trace_file);
1126 doc_info.number()++;
void actions_before_newton_convergence_check()
Update no slip before Newton convergence check.
OneDLagrangianMesh< FSIHermiteBeamElement > * wall_mesh_pt()
Access function for the wall mesh.
int main(int argc, char *argv[])
void actions_before_newton_solve()
Update the problem specs before solve (empty)
~FSICollapsibleChannelProblem()
Destructor (empty)
double Lambda_sq
Pseudo-solid mass density.
void set_initial_condition()
Apply initial conditions.
SolidMesh * Lagrange_multiplier_mesh_pt
Pointers to mesh of Lagrange multiplier elements.
void create_lagrange_multiplier_elements()
Create elements that enforce prescribed boundary motion by Lagrange multipliers.
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...
MeshAsGeomObject * Wall_geom_object_pt
Geometric object incarnation of the wall mesh.
double Sigma0
2nd Piola Kirchhoff pre-stress. As in Jensen & Heil (2003) paper.
double Q
Fluid structure interaction parameter: Ratio of stresses used for non-dimensionalisation of fluid to ...
double P_up
Default pressure on the left boundary.
ElasticCollapsibleChannelMesh< ELEMENT > * bulk_mesh_pt()
Access function for the specific bulk (fluid) mesh.
double ReSt
Womersley = Reynolds times Strouhal.
void doc_solution(DocInfo &doc_info, ofstream &trace_file)
Doc the solution.
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)
Constructor: The arguments are the number of elements and the lengths of the domain.
double Delta
Boundary layer width.
double Re
Reynolds number.
void actions_after_newton_solve()
Update the problem after solve (empty)
double Fract_in_BL
Fraction of points in boundary layer.
void create_traction_elements(const unsigned &b, Mesh *const &bulk_mesh_pt, Mesh *const &traction_mesh_pt)
Create the prescribed traction elements on boundary b.
void prescribed_traction(const double &t, const Vector< double > &x, const Vector< double > &n, Vector< double > &traction)
Traction applied on the fluid at the left (inflow) boundary.
Upgrade mesh to solid mesh.
Namespace for phyical parameters.
double H
Non-dimensional wall thickness. As in Jensen & Heil (2003) paper.
ElasticCollapsibleChannelMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the "bulk" mesh.
ConstitutiveLaw * Constitutive_law_pt
Constitutive law used to determine the mesh deformation.
double squash_fct(const double &s)
Mapping [0,1] -> [0,1] that re-distributes nodal points across the channel width. ...
double P_ext
External pressure.
void delete_traction_elements(Mesh *const &traction_mesh_pt)
Delete prescribed traction elements from the surface mesh.
double Nu
Pseudo-solid Poisson ratio.
void delete_lagrange_multiplier_elements()