29 #include "navier_stokes.h"
30 #include "multi_physics.h"
33 #include "meshes/channel_with_leaflet_mesh.h"
36 #include "meshes/one_d_lagrangian_mesh.h"
40 using namespace oomph;
72 double flux(
const double& t)
102 void position(
const Vector<double>& zeta, Vector<double>& r)
const
113 void position(
const unsigned& t,
const Vector<double>& zeta,
114 Vector<double>& r)
const
128 DenseMatrix<double> &drdzeta,
129 RankThreeTensor<double> &ddrdzeta)
const
163 template<
class ELEMENT>
178 const double& lright,
const double& hleaflet,
180 const unsigned& nleft,
const unsigned& nright,
181 const unsigned& ny1,
const unsigned& ny2,
194 void actions_after_adapt();
205 return Fluid_mesh_pt;
209 void doc_solution(DocInfo& doc_info, ofstream& trace);
216 double t=time_pt()->time();
223 unsigned num_nod= Fluid_mesh_pt->nboundary_node(ibound);
224 for (
unsigned inod=0;inod<num_nod;inod++)
226 double ycoord = Fluid_mesh_pt->boundary_node_pt(ibound,inod)->x(1);
227 double uy = ampl*6.0*ycoord/Htot*(1.0-ycoord/Htot);
228 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(0,uy);
229 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(1,0.0);
238 Fluid_mesh_pt->node_update();
264 template <
class ELEMENT>
267 const double& lright,
268 const double& hleaflet,
270 const unsigned& nleft,
271 const unsigned& nright,
274 const double& x_0) : Htot(htot)
280 BDF<2>* fluid_time_stepper_pt=
new BDF<2>;
281 add_time_stepper_pt(fluid_time_stepper_pt);
284 Steady<2>* wall_time_stepper_pt=
new Steady<2>;
285 add_time_stepper_pt(wall_time_stepper_pt);
295 unsigned n_wall_el=5;
296 Wall_mesh_pt =
new OneDLagrangianMesh<FSIHermiteBeamElement>
297 (n_wall_el,hleaflet,undeformed_wall_pt,wall_time_stepper_pt);
305 MeshAsGeomObject* wall_geom_object_pt=
309 Fluid_mesh_pt =
new RefineableAlgebraicChannelWithLeafletMesh<ELEMENT>(
315 fluid_time_stepper_pt);
318 Z2ErrorEstimator* error_estimator_pt=
new Z2ErrorEstimator;
319 Fluid_mesh_pt->spatial_error_estimator_pt()=error_estimator_pt;
340 for(
unsigned ibound=0;ibound<num_bound;ibound++)
343 for (
unsigned inod=0;inod<num_nod;inod++)
364 for (
unsigned inod=0;inod<num_nod;inod++)
366 double ycoord =
Fluid_mesh_pt->boundary_node_pt(ibound,inod)->x(1);
367 double uy = 6.0*ycoord/htot*(1.0-ycoord/htot);
368 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(0,uy);
369 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(1,0.0);
385 wall_mesh_pt()->boundary_node_pt(b,0)->pin_position(1,0);
395 for(
unsigned e=0;e<n_element;e++)
398 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(
Fluid_mesh_pt->element_pt(e));
410 RefineableNavierStokesEquations<2>::
417 for(
unsigned e=0;e<n_element;e++)
420 FSIHermiteBeamElement *elem_pt =
421 dynamic_cast<FSIHermiteBeamElement*
>(
wall_mesh_pt()->element_pt(e));
430 elem_pt->undeformed_beam_pt() = undeformed_wall_pt;
433 elem_pt->enable_fluid_loading_on_both_sides();
439 elem_pt->set_normal_pointing_out_of_fluid();
452 for(
unsigned ibound=4;ibound<6;ibound++ )
455 for (
unsigned inod=0;inod<num_nod;inod++)
458 set_auxiliary_node_update_fct_pt(
459 FSI_functions::apply_no_slip_on_moving_wall);
471 FSI_functions::setup_fluid_load_info_for_solid_elements<ELEMENT,2>
476 FSI_functions::setup_fluid_load_info_for_solid_elements<ELEMENT,2>
480 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
486 if (CommandLineArgs::Argc==1)
491 GMRES<CRDoubleMatrix>* iterative_linear_solver_pt =
492 new GMRES<CRDoubleMatrix>;
495 iterative_linear_solver_pt->max_iter() = 200;
498 linear_solver_pt()=iterative_linear_solver_pt;
503 FSIPreconditioner* prec_pt=
new FSIPreconditioner(
this);
519 #ifdef OOMPH_HAS_HYPRE
523 HyprePreconditioner* p_preconditioner_pt =
new HyprePreconditioner;
526 p_preconditioner_pt->disable_doc_time();
529 Hypre_default_settings::
530 set_defaults_for_2D_poisson_problem(p_preconditioner_pt);
538 HyprePreconditioner* f_preconditioner_pt =
new HyprePreconditioner;
541 f_preconditioner_pt->disable_doc_time();
545 Hypre_default_settings::
546 set_defaults_for_navier_stokes_momentum_block(f_preconditioner_pt);
554 prec_pt->use_block_triangular_version_with_fluid_on_solid();
557 iterative_linear_solver_pt->preconditioner_pt()= prec_pt;
571 template<
class ELEMENT>
575 RefineableNavierStokesEquations<2>::
576 unpin_all_pressure_dofs(Fluid_mesh_pt->element_pt());
579 RefineableNavierStokesEquations<2>::
580 pin_redundant_nodal_pressures(Fluid_mesh_pt->element_pt());
591 for(
unsigned ibound=4;ibound<6;ibound++ )
593 unsigned num_nod= Fluid_mesh_pt->nboundary_node(ibound);
594 for (
unsigned inod=0;inod<num_nod;inod++)
596 Fluid_mesh_pt->boundary_node_pt(ibound, inod)->
597 set_auxiliary_node_update_fct_pt(
598 FSI_functions::apply_no_slip_on_moving_wall);
615 FSI_functions::setup_fluid_load_info_for_solid_elements<ELEMENT,2>
616 (
this,4,Fluid_mesh_pt,Wall_mesh_pt,face);
620 FSI_functions::setup_fluid_load_info_for_solid_elements<ELEMENT,2>
621 (
this,5,Fluid_mesh_pt,Wall_mesh_pt,face);
632 template<
class ELEMENT>
644 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
646 some_file.open(filename);
647 Fluid_mesh_pt->output(some_file,npts);
651 sprintf(filename,
"%s/wall_soln%i.dat",doc_info.directory().c_str(),
653 some_file.open(filename);
654 Wall_mesh_pt->output(some_file,npts);
658 unsigned n_el_wall=Wall_mesh_pt->nelement();
659 Node* tip_node_pt=Wall_mesh_pt->finite_element_pt(n_el_wall-1)->node_pt(1);
662 double time=time_pt()->time();
667 << tip_node_pt->x(0) <<
" "
668 << tip_node_pt->x(1) <<
" "
669 << tip_node_pt->dposition_dt(0) <<
" "
670 << tip_node_pt->dposition_dt(1) <<
" "
671 << doc_info.number() <<
" "
681 sprintf(filename,
"%s/fluid_boundary_elements_front_%i.dat",
682 doc_info.directory().c_str(),
684 some_file.open(filename);
685 unsigned nel= Fluid_mesh_pt->nboundary_element(bound);
686 for (
unsigned e=0;e<nel;e++)
688 dynamic_cast<ELEMENT*
>(Fluid_mesh_pt->boundary_element_pt(bound,e))
689 ->output(some_file,npts);
697 sprintf(filename,
"%s/fluid_boundary_elements_back_%i.dat",
698 doc_info.directory().c_str(),
700 some_file.open(filename);
701 nel= Fluid_mesh_pt->nboundary_element(bound);
702 for (
unsigned e=0;e<nel;e++)
704 dynamic_cast<ELEMENT*
>(Fluid_mesh_pt->boundary_element_pt(bound,e))
705 ->output(some_file,npts);
711 sprintf(filename,
"%s/wall_normal_%i.dat",
712 doc_info.directory().c_str(),
714 some_file.open(filename);
715 nel=Wall_mesh_pt->nelement();
718 Vector<double> xi(1);
720 for (
unsigned e=0;e<nel;e++)
723 FSIHermiteBeamElement* el_pt=
724 dynamic_cast<FSIHermiteBeamElement*
>(Wall_mesh_pt->element_pt(e));
727 for (
unsigned i=0;i<npts;i++)
729 s[0]=-1.0+2.0*double(i)/double(npts-1);
732 el_pt->interpolated_x(s,x);
735 el_pt->get_normal(s,N);
738 el_pt->interpolated_xi(s,xi);
740 some_file << x[0] <<
" " << x[1] <<
" "
741 << N[0] <<
" " << N[1] <<
" "
742 << xi[0] << std::endl;
756 int main(
int argc,
char* argv[])
759 CommandLineArgs::setup(argc,argv);
779 AlgebraicElement<RefineableQTaylorHoodElement<2> > >
780 problem(lleft,lright,hleaflet,
781 htot,nleft,nright,ny1,ny2,x_0);
785 doc_info.set_directory(
"RESLT");
790 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
791 trace.open(filename);
796 if (CommandLineArgs::Argc>1)
805 problem.initialise_dt(dt);
808 problem.doc_solution(doc_info,trace);
814 unsigned n_increment=4;
816 if (CommandLineArgs::Argc>1)
822 unsigned max_adapt=3;
825 for (
unsigned i=0;i<n_increment;i++)
832 std::cout <<
"Computing a steady solution for Re="
834 problem.steady_newton_solve(max_adapt);
835 problem.doc_solution(doc_info,trace);
851 for (
unsigned istep=0;istep<nstep;istep++)
854 problem.unsteady_newton_solve(dt,max_adapt,first);
857 problem.doc_solution(doc_info,trace);
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
void doc_solution(DocInfo &doc_info, ofstream &trace)
Doc the solution.
RefineableAlgebraicChannelWithLeafletMesh< ELEMENT > * Fluid_mesh_pt
Pointer to the fluid mesh.
~FSIChannelWithLeafletProblem()
Destructor empty.
double Htot
Total height of the domain.
void actions_before_newton_solve()
Actions before solve (empty)
OneDLagrangianMesh< FSIHermiteBeamElement > * Wall_mesh_pt
Pointer to the "wall" mesh.
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 ...
OneDLagrangianMesh< FSIHermiteBeamElement > * wall_mesh_pt()
Access function to the wall mesh.
void actions_after_newton_solve()
Actions after solve (empty)
void actions_before_implicit_timestep()
Update the inflow velocity.
void actions_after_adapt()
Actions after adaptation.
GeomObject * Leaflet_pt
Pointer to the GeomObject that represents the wall.
RefineableAlgebraicChannelWithLeafletMesh< ELEMENT > * fluid_mesh_pt()
Access function to fluid mesh.
void actions_before_newton_convergence_check()
Update before checking Newton convergence: Update the nodal positions in the fluid mesh in response t...
int main(int argc, char *argv[])
Driver code – pass a command line argument if you want to run the code in validation mode where it on...
double ReSt
Womersley number: Product of Reynolds and Strouhal numbers.
double Period
Period for fluctuations in flux.
double Q
Fluid structure interaction parameter: Ratio of stresses used for non-dimensionalisation of fluid to ...
double Min_flux
Min. flux.
double Re
Reynolds number.
double flux(const double &t)
Flux: Pulsatile flow fluctuating between Min_flux and Max_flux with period Period.
double Max_flux
Max. flux.
double H
Non-dimensional wall thickness.