33 #include "navier_stokes.h" 34 #include "multi_physics.h" 37 #include "meshes/channel_with_leaflet_mesh.h" 40 #include "meshes/one_d_lagrangian_mesh.h" 44 using namespace oomph;
76 double flux(
const double& t)
79 (Max_flux-
Min_flux)*0.5*(1.0-cos(2.0*MathematicalConstants::Pi*t/Period));
106 void position(
const Vector<double>& zeta, Vector<double>& r)
const 117 void position(
const unsigned& t,
const Vector<double>& zeta,
118 Vector<double>& r)
const 132 DenseMatrix<double> &drdzeta,
133 RankThreeTensor<double> &ddrdzeta)
const 167 template<
class ELEMENT>
182 const double& lright,
const double& hleaflet,
184 const unsigned& nleft,
const unsigned& nright,
185 const unsigned& ny1,
const unsigned& ny2,
198 void actions_after_adapt();
209 return Fluid_mesh_pt;
213 void doc_solution(DocInfo& doc_info, ofstream& trace);
220 double t=time_pt()->time();
227 unsigned num_nod= Fluid_mesh_pt->nboundary_node(ibound);
228 for (
unsigned inod=0;inod<num_nod;inod++)
230 double ycoord = Fluid_mesh_pt->boundary_node_pt(ibound,inod)->x(1);
231 double uy = ampl*6.0*ycoord/Htot*(1.0-ycoord/Htot);
232 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(0,uy);
233 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(1,0.0);
242 Fluid_mesh_pt->node_update();
268 template <
class ELEMENT>
271 const double& lright,
272 const double& hleaflet,
274 const unsigned& nleft,
275 const unsigned& nright,
278 const double& x_0) : Htot(htot)
284 BDF<2>* fluid_time_stepper_pt=
new BDF<2>;
285 add_time_stepper_pt(fluid_time_stepper_pt);
288 Steady<2>* wall_time_stepper_pt=
new Steady<2>;
289 add_time_stepper_pt(wall_time_stepper_pt);
299 unsigned n_wall_el=5;
300 Wall_mesh_pt =
new OneDLagrangianMesh<FSIHermiteBeamElement>
301 (n_wall_el,hleaflet,undeformed_wall_pt,wall_time_stepper_pt);
309 MeshAsGeomObject* wall_geom_object_pt=
313 Fluid_mesh_pt =
new RefineableAlgebraicChannelWithLeafletMesh<ELEMENT>(
319 fluid_time_stepper_pt);
322 Z2ErrorEstimator* error_estimator_pt=
new Z2ErrorEstimator;
323 Fluid_mesh_pt->spatial_error_estimator_pt()=error_estimator_pt;
344 for(
unsigned ibound=0;ibound<num_bound;ibound++)
347 for (
unsigned inod=0;inod<num_nod;inod++)
368 for (
unsigned inod=0;inod<num_nod;inod++)
370 double ycoord =
Fluid_mesh_pt->boundary_node_pt(ibound,inod)->x(1);
371 double uy = 6.0*ycoord/htot*(1.0-ycoord/htot);
372 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(0,uy);
373 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(1,0.0);
389 wall_mesh_pt()->boundary_node_pt(b,0)->pin_position(1,0);
399 for(
unsigned e=0;e<n_element;e++)
402 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(
Fluid_mesh_pt->element_pt(e));
414 RefineableNavierStokesEquations<2>::
421 for(
unsigned e=0;e<n_element;e++)
424 FSIHermiteBeamElement *elem_pt =
425 dynamic_cast<FSIHermiteBeamElement*
>(
wall_mesh_pt()->element_pt(e));
434 elem_pt->undeformed_beam_pt() = undeformed_wall_pt;
437 elem_pt->enable_fluid_loading_on_both_sides();
443 elem_pt->set_normal_pointing_out_of_fluid();
456 for(
unsigned ibound=4;ibound<6;ibound++ )
459 for (
unsigned inod=0;inod<num_nod;inod++)
462 set_auxiliary_node_update_fct_pt(
463 FSI_functions::apply_no_slip_on_moving_wall);
475 FSI_functions::setup_fluid_load_info_for_solid_elements<ELEMENT,2>
480 FSI_functions::setup_fluid_load_info_for_solid_elements<ELEMENT,2>
484 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
490 if (CommandLineArgs::Argc==1)
495 GMRES<CRDoubleMatrix>* iterative_linear_solver_pt =
496 new GMRES<CRDoubleMatrix>;
499 iterative_linear_solver_pt->max_iter() = 200;
502 linear_solver_pt()=iterative_linear_solver_pt;
507 FSIPreconditioner* prec_pt=
new FSIPreconditioner(
this);
510 prec_pt->set_navier_stokes_mesh(Fluid_mesh_pt);
513 prec_pt->set_wall_mesh(Wall_mesh_pt);
523 #ifdef OOMPH_HAS_HYPRE 527 HyprePreconditioner* p_preconditioner_pt =
new HyprePreconditioner;
530 p_preconditioner_pt->disable_doc_time();
533 Hypre_default_settings::
534 set_defaults_for_2D_poisson_problem(p_preconditioner_pt);
542 HyprePreconditioner* f_preconditioner_pt =
new HyprePreconditioner;
545 f_preconditioner_pt->disable_doc_time();
549 Hypre_default_settings::
550 set_defaults_for_navier_stokes_momentum_block(f_preconditioner_pt);
558 prec_pt->use_block_triangular_version_with_fluid_on_solid();
561 iterative_linear_solver_pt->preconditioner_pt()= prec_pt;
575 template<
class ELEMENT>
579 RefineableNavierStokesEquations<2>::
583 RefineableNavierStokesEquations<2>::
595 for(
unsigned ibound=4;ibound<6;ibound++ )
598 for (
unsigned inod=0;inod<num_nod;inod++)
601 set_auxiliary_node_update_fct_pt(
602 FSI_functions::apply_no_slip_on_moving_wall);
619 FSI_functions::setup_fluid_load_info_for_solid_elements<ELEMENT,2>
624 FSI_functions::setup_fluid_load_info_for_solid_elements<ELEMENT,2>
636 template<
class ELEMENT>
648 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
650 some_file.open(filename);
655 sprintf(filename,
"%s/wall_soln%i.dat",doc_info.directory().c_str(),
657 some_file.open(filename);
663 Node* tip_node_pt=
Wall_mesh_pt->finite_element_pt(n_el_wall-1)->node_pt(1);
666 double time=time_pt()->time();
671 << tip_node_pt->x(0) <<
" " 672 << tip_node_pt->x(1) <<
" " 673 << tip_node_pt->dposition_dt(0) <<
" " 674 << tip_node_pt->dposition_dt(1) <<
" " 675 << doc_info.number() <<
" " 685 sprintf(filename,
"%s/fluid_boundary_elements_front_%i.dat",
686 doc_info.directory().c_str(),
688 some_file.open(filename);
690 for (
unsigned e=0;e<nel;e++)
692 dynamic_cast<ELEMENT*
>(
Fluid_mesh_pt->boundary_element_pt(bound,e))
693 ->output(some_file,npts);
701 sprintf(filename,
"%s/fluid_boundary_elements_back_%i.dat",
702 doc_info.directory().c_str(),
704 some_file.open(filename);
706 for (
unsigned e=0;e<nel;e++)
708 dynamic_cast<ELEMENT*
>(
Fluid_mesh_pt->boundary_element_pt(bound,e))
709 ->output(some_file,npts);
715 sprintf(filename,
"%s/wall_normal_%i.dat",
716 doc_info.directory().c_str(),
718 some_file.open(filename);
722 Vector<double> xi(1);
724 for (
unsigned e=0;e<nel;e++)
727 FSIHermiteBeamElement* el_pt=
728 dynamic_cast<FSIHermiteBeamElement*
>(
Wall_mesh_pt->element_pt(e));
731 for (
unsigned i=0;i<npts;i++)
733 s[0]=-1.0+2.0*double(i)/double(npts-1);
736 el_pt->interpolated_x(s,x);
739 el_pt->get_normal(s,N);
742 el_pt->interpolated_xi(s,xi);
744 some_file << x[0] <<
" " << x[1] <<
" " 745 << N[0] <<
" " << N[1] <<
" " 746 << xi[0] << std::endl;
760 int main(
int argc,
char* argv[])
763 CommandLineArgs::setup(argc,argv);
783 AlgebraicElement<RefineableQTaylorHoodElement<2> > >
784 problem(lleft,lright,hleaflet,
785 htot,nleft,nright,ny1,ny2,x_0);
789 doc_info.set_directory(
"RESLT");
794 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
795 trace.open(filename);
800 if (CommandLineArgs::Argc>1)
809 problem.initialise_dt(dt);
812 problem.doc_solution(doc_info,trace);
818 unsigned n_increment=4;
820 if (CommandLineArgs::Argc>1)
826 unsigned max_adapt=3;
829 for (
unsigned i=0;i<n_increment;i++)
836 std::cout <<
"Computing a steady solution for Re=" 838 problem.steady_newton_solve(max_adapt);
839 problem.doc_solution(doc_info,trace);
855 for (
unsigned istep=0;istep<nstep;istep++)
858 problem.unsteady_newton_solve(dt,max_adapt,first);
861 problem.doc_solution(doc_info,trace);
void actions_after_adapt()
Actions after adaptation.
double Period
Period for fluctuations in flux.
FSIChannelWithLeafletProblem(const double &lleft, const double &lright, const double &hleaflet, const double &htot, const unsigned &nleft, const unsigned &nright, const unsigned &ny1, const unsigned &ny2, const double &x_0)
Constructor: Pass the lenght of the domain at the left of the leaflet lleft,the lenght of the domain ...
int main(int argc, char *argv[])
void actions_before_implicit_timestep()
Update the inflow velocity.
OneDLagrangianMesh< FSIHermiteBeamElement > * wall_mesh_pt()
Access function to the wall mesh.
double Q
Fluid structure interaction parameter: Ratio of stresses used for non-dimensionalisation of fluid to ...
~FSIChannelWithLeafletProblem()
Destructor empty.
double ReSt
Womersley number: Product of Reynolds and Strouhal numbers.
void actions_before_newton_solve()
Actions before solve (empty)
double Max_flux
Max. flux.
void doc_solution(DocInfo &doc_info, ofstream &trace)
Doc the solution.
double Htot
Total height of the domain.
void actions_before_newton_convergence_check()
Update before checking Newton convergence: Update the nodal positions in the fluid mesh in response t...
double Re
Reynolds number.
double flux(const double &t)
Flux: Pulsatile flow fluctuating between Min_flux and Max_flux with period Period.
void actions_after_newton_solve()
Actions after solve (empty)
double H
Non-dimensional wall thickness.
double Min_flux
Min. flux.
RefineableAlgebraicChannelWithLeafletMesh< ELEMENT > * Fluid_mesh_pt
Pointer to the fluid mesh.
OneDLagrangianMesh< FSIHermiteBeamElement > * Wall_mesh_pt
Pointer to the "wall" mesh.
RefineableAlgebraicChannelWithLeafletMesh< ELEMENT > * fluid_mesh_pt()
Access function to fluid mesh.
GeomObject * Leaflet_pt
Pointer to the GeomObject that represents the wall.