36 #include "navier_stokes.h" 43 using namespace oomph;
64 if (s<0.5*Fract_in_BL)
68 else if (s>1.0-0.5*Fract_in_BL)
70 y=2.0*Delta/Fract_in_BL*s+1.0-2.0*Delta/
Fract_in_BL;
74 y=(1.0-2.0*
Delta)/(1.0-Fract_in_BL)*s+
131 const double& a,
const double& period, Time* time_pt) :
132 GeomObject(1,2), H(h), Length(l), X_left(x_left), A(a), B(0.0), T(period),
147 void position(
const unsigned& t,
const Vector<double>&zeta,
148 Vector<double>& r)
const 150 using namespace MathematicalConstants;
154 if (Time_pt->time(t)<T)
156 ramp=0.5*(1.0-cos(Pi*Time_pt->time(t)/T));
160 r[0] = zeta[0]+X_left
161 -B*A*sin(2.0*3.14159*zeta[0]/Length)*
162 sin(2.0*Pi*(Time_pt->time(t))/T)*ramp;
164 r[1] = H+A*((Length-zeta[0])*zeta[0])/pow(0.5*Length,2)*
165 sin(2.0*Pi*(Time_pt->time(t))/T)*ramp;
171 void position(
const Vector<double>&zeta, Vector<double>& r)
const 173 position (0, zeta, r);
223 const Vector<double>& x,
224 const Vector<double>& n,
225 Vector<double>& traction)
239 template <
class ELEMENT>
249 const unsigned& ncollapsible,
250 const unsigned& ndown,
253 const double& lcollapsible,
256 const double& amplitude,
257 const double& period);
299 void actions_before_implicit_timestep();
302 void actions_before_adapt();
305 void actions_after_adapt();
308 void set_initial_condition();
311 void doc_solution(DocInfo& doc_info, ofstream& trace_file);
317 void create_traction_elements(
const unsigned &b,
318 Mesh*
const &bulk_mesh_pt,
319 Mesh*
const &surface_mesh_pt);
322 void delete_traction_elements(Mesh*
const &surface_mesh_pt);
329 unsigned Ncollapsible;
357 Mesh* Surface_mesh_pt;
373 template <
class ELEMENT>
376 const unsigned& ncollapsible,
377 const unsigned& ndown,
380 const double& lcollapsible,
383 const double& amplitude,
384 const double& period)
388 Ncollapsible=ncollapsible;
394 Lcollapsible=lcollapsible;
400 Problem::Max_residuals=10000;
405 add_time_stepper_pt(
new BDF<2>);
409 double length=lcollapsible;
420 nup, ncollapsible, ndown, ny,
421 lup, lcollapsible, ldown, ly,
423 #ifdef USE_BL_SQUASH_FCT 432 nup, ncollapsible, ndown, ny,
433 lup, lcollapsible, ldown, ly,
435 #ifdef USE_BL_SQUASH_FCT 446 Surface_mesh_pt =
new Mesh;
450 create_traction_elements(5,Bulk_mesh_pt,Surface_mesh_pt);
453 add_sub_mesh(Bulk_mesh_pt);
454 add_sub_mesh(Surface_mesh_pt);
463 Z2ErrorEstimator* error_estimator_pt=
new Z2ErrorEstimator;
465 (Bulk_mesh_pt)->spatial_error_estimator_pt()=error_estimator_pt;
471 unsigned n_element=Bulk_mesh_pt->nelement();
472 for(
unsigned e=0;e<n_element;e++)
475 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
489 unsigned n_el=Surface_mesh_pt->nelement();
490 for(
unsigned e=0;e<n_el;e++)
493 NavierStokesTractionElement<ELEMENT> *el_pt =
494 dynamic_cast< NavierStokesTractionElement<ELEMENT>*
>(
495 Surface_mesh_pt->element_pt(e));
508 unsigned num_nod= bulk_mesh_pt()->nboundary_node(ibound);
509 for (
unsigned inod=0;inod<num_nod;inod++)
511 for(
unsigned i=0;i<2;i++)
513 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(i);
519 for(
unsigned ib=2;ib<5;ib++)
521 num_nod= bulk_mesh_pt()->nboundary_node(ib);
522 for (
unsigned inod=0;inod<num_nod;inod++)
524 for(
unsigned i=0;i<2;i++)
526 bulk_mesh_pt()->boundary_node_pt(ib, inod)->pin(i);
533 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
534 for (
unsigned inod=0;inod<num_nod;inod++)
536 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
542 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
543 for (
unsigned inod=0;inod<num_nod;inod++)
545 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
555 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
556 unsigned control_nod=num_nod/2;
557 Left_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
561 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
562 control_nod=num_nod/2;
563 Right_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
566 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
576 template <
class ELEMENT>
578 ofstream& trace_file)
588 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
590 some_file.open(filename);
591 bulk_mesh_pt()->output(some_file,npts);
596 Vector<double> zeta(1);
597 zeta[0]=0.5*Lcollapsible;
598 Vector<double> wall_point(2);
599 Wall_pt->position(zeta,wall_point);
602 trace_file << time_pt()->time() <<
" " 603 << wall_point[1] <<
" " 604 << Left_node_pt->value(0) <<
" " 605 << Right_node_pt->value(0) <<
" " 609 sprintf(filename,
"%s/wall%i.dat",doc_info.directory().c_str(),
611 some_file.open(filename);
613 for (
unsigned i=0;i<nplot;i++)
615 zeta[0]=double(i)/double(nplot-1)*Lcollapsible;
616 Wall_pt->position(zeta,wall_point);
617 some_file << wall_point[0] <<
" " 618 << wall_point[1] << std::endl;
630 template <
class ELEMENT>
632 const unsigned &b, Mesh*
const &bulk_mesh_pt, Mesh*
const &surface_mesh_pt)
635 unsigned n_element = bulk_mesh_pt->nboundary_element(b);
638 for(
unsigned e=0;e<n_element;e++)
641 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
> 642 (bulk_mesh_pt->boundary_element_pt(b,e));
645 int face_index = bulk_mesh_pt->face_index_at_boundary(b,e);
648 NavierStokesTractionElement<ELEMENT>* traction_element_pt =
649 new NavierStokesTractionElement<ELEMENT>(bulk_elem_pt,face_index);
652 surface_mesh_pt->add_element_pt(traction_element_pt);
662 template<
class ELEMENT>
667 unsigned n_element = surface_mesh_pt->nelement();
670 for(
unsigned e=0;e<n_element;e++)
673 delete surface_mesh_pt->element_pt(e);
677 surface_mesh_pt->flush_element_and_node_storage();
687 template <
class ELEMENT>
692 if (time_stepper_pt()->type()!=
"BDF")
694 std::ostringstream error_stream;
696 <<
"Timestepper has to be from the BDF family!\n" 697 <<
"You have specified a timestepper from the " 698 << time_stepper_pt()->type() <<
" family" << std::endl;
700 throw OomphLibError(error_stream.str(),
701 OOMPH_CURRENT_FUNCTION,
702 OOMPH_EXCEPTION_LOCATION);
706 bulk_mesh_pt()->node_update();
709 unsigned num_nod = bulk_mesh_pt()->nnode();
710 for (
unsigned n=0;n<num_nod;n++)
714 x[0]=bulk_mesh_pt()->node_pt(n)->x(0);
715 x[1]=bulk_mesh_pt()->node_pt(n)->x(1);
718 bulk_mesh_pt()->node_pt(n)->set_value(0,6.0*(x[1]/Ly)*(1.0-(x[1]/Ly)));
719 bulk_mesh_pt()->node_pt(n)->set_value(1,0.0);
723 bulk_mesh_pt()->assign_initial_values_impulsive();
734 template <
class ELEMENT>
738 bulk_mesh_pt()->node_update();
743 unsigned num_nod=bulk_mesh_pt()->nboundary_node(ibound);
744 for (
unsigned inod=0;inod<num_nod;inod++)
747 Node* node_pt=bulk_mesh_pt()->boundary_node_pt(ibound,inod);
750 FSI_functions::apply_no_slip_on_moving_wall(node_pt);
760 template<
class ELEMENT>
764 delete_traction_elements(Surface_mesh_pt);
767 rebuild_global_mesh();
775 template<
class ELEMENT>
780 create_traction_elements(5,Bulk_mesh_pt,Surface_mesh_pt);
783 rebuild_global_mesh();
787 unsigned n_element=Surface_mesh_pt->nelement();
788 for(
unsigned e=0;e<n_element;e++)
791 NavierStokesTractionElement<ELEMENT> *el_pt =
792 dynamic_cast<NavierStokesTractionElement<ELEMENT>*
>(
793 Surface_mesh_pt->element_pt(e));
808 int main(
int argc,
char* argv[])
812 CommandLineArgs::setup(argc,argv);
815 unsigned coarsening_factor=1;
816 if (CommandLineArgs::Argc>1)
822 unsigned nup=20/coarsening_factor;
823 unsigned ncollapsible=40/coarsening_factor;
824 unsigned ndown=40/coarsening_factor;
825 unsigned ny=16/coarsening_factor;
829 double lcollapsible=10.0;
834 double amplitude=1.0e-2;
846 doc_info.set_directory(
"RESLT");
851 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
852 trace_file.open(filename);
859 problem(nup, ncollapsible, ndown, ny,
860 lup, lcollapsible, ldown, ly,
867 problem(nup, ncollapsible, ndown, ny,
868 lup, lcollapsible, ldown, ly,
877 unsigned nsteps_per_period=40;
883 unsigned nstep=nsteps_per_period*nperiod;
884 if (CommandLineArgs::Argc>1)
890 double dt=period/double(nsteps_per_period);
896 problem.time_pt()->time()=t_min;
897 problem.initialise_dt(dt);
914 if (CommandLineArgs::Argc>1)
925 unsigned max_adapt=10;
930 for (
unsigned istep=0;istep<nstep;istep++)
936 problem.unsteady_newton_solve(dt, max_adapt, first);
942 problem.unsteady_newton_solve(dt);
MyAlgebraicCollapsibleChannelMesh< ELEMENT > * bulk_mesh_pt()
Access function for the specific mesh.
void doc_solution(DocInfo &doc_info, ofstream &trace_file)
Doc the solution.
double & amplitude()
Access function to the amplitude.
OscillatingWall(const double &h, const double &x_left, const double &l, const double &a, const double &period, Time *time_pt)
Constructor : It's a 2D object, parametrised by one Lagrangian coordinate. Arguments: height at ends...
void delete_traction_elements(Mesh *const &surface_mesh_pt)
Delete prescribed traction elements from the surface mesh.
double P_up
Default pressure on the left boundary.
Collapsible channel mesh with algebraic node update.
void actions_after_adapt()
Actions after adapt: Rebuild the mesh of prescribed traction elements.
double ReSt
Womersley = Reynolds times Strouhal.
void actions_before_implicit_timestep()
Update the velocity boundary condition on the moving wall.
RefineableCollapsibleChannelMesh< ELEMENT > * bulk_mesh_pt()
Access function for the specific mesh.
void set_initial_condition()
Apply initial conditions.
int main(int argc, char *argv[])
double Delta
Boundary layer width.
~OscillatingWall()
Destructor: Empty.
double Re
Reynolds number.
void actions_before_adapt()
Actions before adapt: Wipe the mesh of prescribed traction elements.
~CollapsibleChannelProblem()
Empty destructor.
MyAlgebraicCollapsibleChannelMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the "bulk" mesh.
double Fract_in_BL
Fraction of points in boundary layer.
void prescribed_traction(const double &t, const Vector< double > &x, const Vector< double > &n, Vector< double > &traction)
Traction required at the left boundary.
void actions_before_newton_solve()
Update the problem specs before solve (empty)
Namespace for phyical parameters.
void actions_after_newton_solve()
Update the problem after solve (empty)
void create_traction_elements(const unsigned &b, Mesh *const &bulk_mesh_pt, Mesh *const &surface_mesh_pt)
Create the traction elements.
void position(const unsigned &t, const Vector< double > &zeta, Vector< double > &r) const
Position vector at Lagrangian coordinate zeta at time level t.
double squash_fct(const double &s)
Mapping [0,1] -> [0,1] that re-distributes nodal points across the channel width. ...
unsigned ngeom_data() const
Number of geometric Data in GeomObject: None.
CollapsibleChannelProblem(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 double &litude, const double &period)
Constructor : the arguments are the number of elements, the length of the domain and the amplitude an...
double & period()
Access function to the period.
void position(const Vector< double > &zeta, Vector< double > &r) const
"Current" position vector at Lagrangian coordinate zeta
MyRefineableAlgebraicCollapsibleChannelMesh< ELEMENT > * bulk_mesh_pt()
Access function for the specific mesh.