36 #include "navier_stokes.h" 39 #include "meshes/collapsible_channel_mesh.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+
130 const double& a,
const double& period, Time* time_pt) :
131 GeomObject(1,2), H(h), Length(l), X_left(x_left), A(a), B(0.0), T(period),
146 void position(
const unsigned& t,
const Vector<double>&zeta,
147 Vector<double>& r)
const 149 using namespace MathematicalConstants;
153 if (Time_pt->time(t)<T)
155 ramp=0.5*(1.0-cos(Pi*Time_pt->time(t)/T));
159 r[0] = zeta[0]+X_left
160 -B*A*sin(2.0*3.14159*zeta[0]/Length)*
161 sin(2.0*Pi*(Time_pt->time(t))/T)*ramp;
163 r[1] = H+A*((Length-zeta[0])*zeta[0])/pow(0.5*Length,2)*
164 sin(2.0*Pi*(Time_pt->time(t))/T)*ramp;
170 void position(
const Vector<double>&zeta, Vector<double>& r)
const 172 position (0, zeta, r);
222 const Vector<double>& x,
223 const Vector<double>& n,
224 Vector<double>& traction)
238 template <
class ELEMENT>
248 const unsigned& ncollapsible,
249 const unsigned& ndown,
252 const double& lcollapsible,
255 const double& amplitude,
256 const double& period);
267 return dynamic_cast<RefineableCollapsibleChannelMesh<ELEMENT>*
> 279 void actions_before_implicit_timestep();
282 void actions_before_adapt();
285 void actions_after_adapt();
288 void set_initial_condition();
291 void doc_solution(DocInfo& doc_info, ofstream& trace_file);
297 void create_traction_elements(
const unsigned &b,
298 Mesh*
const &bulk_mesh_pt,
299 Mesh*
const &surface_mesh_pt);
302 void delete_traction_elements(Mesh*
const &surface_mesh_pt);
353 template <
class ELEMENT>
356 const unsigned& ncollapsible,
357 const unsigned& ndown,
360 const double& lcollapsible,
363 const double& amplitude,
364 const double& period)
368 Ncollapsible=ncollapsible;
374 Lcollapsible=lcollapsible;
380 Problem::Max_residuals=10000;
385 add_time_stepper_pt(
new BDF<2>);
389 double length=lcollapsible;
397 Bulk_mesh_pt =
new RefineableCollapsibleChannelMesh<ELEMENT>(
398 nup, ncollapsible, ndown, ny,
399 lup, lcollapsible, ldown, ly,
405 #ifdef USE_BL_SQUASH_FCT 411 Bulk_mesh_pt->node_update();
420 Surface_mesh_pt =
new Mesh;
424 create_traction_elements(5,Bulk_mesh_pt,Surface_mesh_pt);
427 add_sub_mesh(Bulk_mesh_pt);
428 add_sub_mesh(Surface_mesh_pt);
434 Z2ErrorEstimator* error_estimator_pt=
new Z2ErrorEstimator;
435 dynamic_cast<RefineableCollapsibleChannelMesh<ELEMENT>*
> 436 (Bulk_mesh_pt)->spatial_error_estimator_pt()=error_estimator_pt;
441 unsigned n_element=Bulk_mesh_pt->nelement();
442 for(
unsigned e=0;e<n_element;e++)
445 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
459 unsigned n_el=Surface_mesh_pt->nelement();
460 for(
unsigned e=0;e<n_el;e++)
463 NavierStokesTractionElement<ELEMENT> *el_pt =
464 dynamic_cast< NavierStokesTractionElement<ELEMENT>*
>(
465 Surface_mesh_pt->element_pt(e));
478 unsigned num_nod= bulk_mesh_pt()->nboundary_node(ibound);
479 for (
unsigned inod=0;inod<num_nod;inod++)
481 for(
unsigned i=0;i<2;i++)
483 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(i);
489 for(
unsigned ib=2;ib<5;ib++)
491 num_nod= bulk_mesh_pt()->nboundary_node(ib);
492 for (
unsigned inod=0;inod<num_nod;inod++)
494 for(
unsigned i=0;i<2;i++)
496 bulk_mesh_pt()->boundary_node_pt(ib, inod)->pin(i);
503 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
504 for (
unsigned inod=0;inod<num_nod;inod++)
506 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
512 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
513 for (
unsigned inod=0;inod<num_nod;inod++)
515 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
525 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
526 unsigned control_nod=num_nod/2;
527 Left_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
531 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
532 control_nod=num_nod/2;
533 Right_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
536 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
546 template <
class ELEMENT>
548 ofstream& trace_file)
558 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
560 some_file.open(filename);
561 bulk_mesh_pt()->output(some_file,npts);
566 Vector<double> zeta(1);
567 zeta[0]=0.5*Lcollapsible;
568 Vector<double> wall_point(2);
569 Wall_pt->position(zeta,wall_point);
572 trace_file << time_pt()->time() <<
" " 573 << wall_point[1] <<
" " 574 << Left_node_pt->value(0) <<
" " 575 << Right_node_pt->value(0) <<
" " 579 sprintf(filename,
"%s/wall%i.dat",doc_info.directory().c_str(),
581 some_file.open(filename);
583 for (
unsigned i=0;i<nplot;i++)
585 zeta[0]=double(i)/double(nplot-1)*Lcollapsible;
586 Wall_pt->position(zeta,wall_point);
587 some_file << wall_point[0] <<
" " 588 << wall_point[1] << std::endl;
600 template <
class ELEMENT>
602 const unsigned &b, Mesh*
const &bulk_mesh_pt, Mesh*
const &surface_mesh_pt)
605 unsigned n_element = bulk_mesh_pt->nboundary_element(b);
608 for(
unsigned e=0;e<n_element;e++)
611 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
> 612 (bulk_mesh_pt->boundary_element_pt(b,e));
615 int face_index = bulk_mesh_pt->face_index_at_boundary(b,e);
618 NavierStokesTractionElement<ELEMENT>* traction_element_pt =
619 new NavierStokesTractionElement<ELEMENT>(bulk_elem_pt,face_index);
622 surface_mesh_pt->add_element_pt(traction_element_pt);
632 template<
class ELEMENT>
637 unsigned n_element = surface_mesh_pt->nelement();
640 for(
unsigned e=0;e<n_element;e++)
643 delete surface_mesh_pt->element_pt(e);
647 surface_mesh_pt->flush_element_and_node_storage();
656 template <
class ELEMENT>
661 if (time_stepper_pt()->type()!=
"BDF")
663 std::ostringstream error_stream;
665 <<
"Timestepper has to be from the BDF family!\n" 666 <<
"You have specified a timestepper from the " 667 << time_stepper_pt()->type() <<
" family" << std::endl;
669 throw OomphLibError(error_stream.str(),
670 OOMPH_CURRENT_FUNCTION,
671 OOMPH_EXCEPTION_LOCATION);
675 bulk_mesh_pt()->node_update();
678 unsigned num_nod = bulk_mesh_pt()->nnode();
679 for (
unsigned n=0;n<num_nod;n++)
683 x[0]=bulk_mesh_pt()->node_pt(n)->x(0);
684 x[1]=bulk_mesh_pt()->node_pt(n)->x(1);
687 bulk_mesh_pt()->node_pt(n)->set_value(0,6.0*(x[1]/Ly)*(1.0-(x[1]/Ly)));
688 bulk_mesh_pt()->node_pt(n)->set_value(1,0.0);
692 bulk_mesh_pt()->assign_initial_values_impulsive();
703 template <
class ELEMENT>
707 bulk_mesh_pt()->node_update();
712 unsigned num_nod=bulk_mesh_pt()->nboundary_node(ibound);
713 for (
unsigned inod=0;inod<num_nod;inod++)
716 Node* node_pt=bulk_mesh_pt()->boundary_node_pt(ibound,inod);
719 FSI_functions::apply_no_slip_on_moving_wall(node_pt);
729 template<
class ELEMENT>
733 delete_traction_elements(Surface_mesh_pt);
736 rebuild_global_mesh();
744 template<
class ELEMENT>
749 create_traction_elements(5,Bulk_mesh_pt,Surface_mesh_pt);
752 rebuild_global_mesh();
755 unsigned n_element=Surface_mesh_pt->nelement();
756 for(
unsigned e=0;e<n_element;e++)
759 NavierStokesTractionElement<ELEMENT> *el_pt =
760 dynamic_cast<NavierStokesTractionElement<ELEMENT>*
>(
761 Surface_mesh_pt->element_pt(e));
776 int main(
int argc,
char* argv[])
780 CommandLineArgs::setup(argc,argv);
783 unsigned coarsening_factor=1;
784 if (CommandLineArgs::Argc>1)
790 unsigned nup=20/coarsening_factor;
791 unsigned ncollapsible=40/coarsening_factor;
792 unsigned ndown=40/coarsening_factor;
793 unsigned ny=16/coarsening_factor;
797 double lcollapsible=10.0;
802 double amplitude=1.0e-2;
814 doc_info.set_directory(
"RESLT");
819 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
820 trace_file.open(filename);
824 problem(nup, ncollapsible, ndown, ny,
825 lup, lcollapsible, ldown, ly,
830 unsigned nsteps_per_period=40;
836 unsigned nstep=nsteps_per_period*nperiod;
837 if (CommandLineArgs::Argc>1)
843 double dt=period/double(nsteps_per_period);
849 problem.time_pt()->time()=t_min;
850 problem.initialise_dt(dt);
866 if (CommandLineArgs::Argc>1)
878 unsigned max_adapt=10;
881 for (
unsigned istep=0;istep<nstep;istep++)
884 problem.unsteady_newton_solve(dt, max_adapt, first);
double Ly
Transverse length.
double Lcollapsible
x-length in the "collapsible" part of the channel
double T
Period of the oscillations.
void doc_solution(DocInfo &doc_info, ofstream &trace_file)
Doc the solution.
double & amplitude()
Access function to the amplitude.
Node * Right_node_pt
Pointer to right control node.
Node * Left_node_pt
Pointer to the left control node.
unsigned Ncollapsible
Number of elements in the x direction in the "collapsible" part of the channel.
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.
Mesh * Surface_mesh_pt
Pointer to the "surface" mesh that contains the applied traction elements.
void actions_after_adapt()
Actions after adapt: Rebuild the mesh of prescribed traction elements.
double ReSt
Womersley = Reynolds times Strouhal.
Time * Time_pt
Pointer to the global time object.
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.
double A
Amplitude of oscillation.
void set_initial_condition()
Apply initial conditions.
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.
unsigned Ndown
Number of elements in the x direction in the downstream part of the channel.
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.
double X_left
x-coordinate of left end
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 Lup
x-length in the upstream part of the channel
RefineableCollapsibleChannelMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the "bulk" mesh.
double B
Relative amplitude of horizontal wall motion.
double Ldown
x-length in the downstream part of the channel
unsigned Ny
Number of elements across the channel.
OscillatingWall * Wall_pt
Pointer to the geometric object that parametrises the "collapsible" wall.
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...
int main(int argc, char *argv[])
unsigned Nup
Number of elements in the x direction in the upstream part of the channel.
double & period()
Access function to the period.
void position(const Vector< double > &zeta, Vector< double > &r) const
"Current" position vector at Lagrangian coordinate zeta