32 #include "navier_stokes.h"
35 #include "meshes/collapsible_channel_mesh.h"
39 using namespace oomph;
116 class OscillatingWall :
public GeomObject
125 OscillatingWall(
const double& h,
const double& x_left,
const double& l,
126 const double& a,
const double& period, Time* time_pt) :
127 GeomObject(1,2), H(h), Length(l), X_left(x_left), A(a), B(0.0), T(period),
135 double& amplitude(){
return A;}
138 double& period(){
return T;}
142 void position(
const unsigned& t,
const Vector<double>&zeta,
143 Vector<double>& r)
const
145 using namespace MathematicalConstants;
149 if (Time_pt->time(t)<T)
151 ramp=0.5*(1.0-cos(Pi*Time_pt->time(t)/T));
155 r[0] = zeta[0]+X_left
156 -B*A*sin(2.0*3.14159*zeta[0]/Length)*
157 sin(2.0*Pi*(Time_pt->time(t))/T)*ramp;
159 r[1] = H+A*((Length-zeta[0])*zeta[0])/pow(0.5*Length,2)*
160 sin(2.0*Pi*(Time_pt->time(t))/T)*ramp;
166 void position(
const Vector<double>&zeta, Vector<double>& r)
const
168 position (0, zeta, r);
172 unsigned ngeom_data()
const {
return 0;}
205 namespace Global_Physical_Variables
217 void prescribed_traction(
const double& t,
218 const Vector<double>& x,
219 const Vector<double>& n,
220 Vector<double>& traction)
234 template <
class ELEMENT>
235 class CollapsibleChannelProblem :
public Problem
243 CollapsibleChannelProblem(
const unsigned& nup,
244 const unsigned& ncollapsible,
245 const unsigned& ndown,
248 const double& lcollapsible,
251 const double& amplitude,
252 const double& period);
255 ~CollapsibleChannelProblem() {}
258 RefineableCollapsibleChannelMesh<ELEMENT>* bulk_mesh_pt()
263 return dynamic_cast<RefineableCollapsibleChannelMesh<ELEMENT>*
>
269 void actions_before_newton_solve(){}
272 void actions_after_newton_solve(){}
275 void actions_before_implicit_timestep();
278 void actions_before_adapt();
281 void actions_after_adapt();
284 void set_initial_condition();
287 void doc_solution(DocInfo& doc_info, ofstream& trace_file);
293 void create_traction_elements(
const unsigned &b,
294 Mesh*
const &bulk_mesh_pt,
295 Mesh*
const &surface_mesh_pt);
298 void delete_traction_elements(Mesh*
const &surface_mesh_pt);
305 unsigned Ncollapsible;
326 OscillatingWall* Wall_pt;
329 RefineableCollapsibleChannelMesh<ELEMENT>* Bulk_mesh_pt;
333 Mesh* Surface_mesh_pt;
349 template <
class ELEMENT>
350 CollapsibleChannelProblem<ELEMENT>::CollapsibleChannelProblem(
352 const unsigned& ncollapsible,
353 const unsigned& ndown,
356 const double& lcollapsible,
359 const double& amplitude,
360 const double& period)
364 Ncollapsible=ncollapsible;
370 Lcollapsible=lcollapsible;
376 Problem::Max_residuals=10000;
381 add_time_stepper_pt(
new BDF<2>);
385 double length=lcollapsible;
389 Wall_pt=
new OscillatingWall(height, x_left, length, amplitude, period,
393 Bulk_mesh_pt =
new RefineableCollapsibleChannelMesh<ELEMENT>(
394 nup, ncollapsible, ndown, ny,
395 lup, lcollapsible, ldown, ly,
401 #ifdef USE_BL_SQUASH_FCT
407 Bulk_mesh_pt->node_update();
416 Surface_mesh_pt =
new Mesh;
420 create_traction_elements(5,Bulk_mesh_pt,Surface_mesh_pt);
423 add_sub_mesh(Bulk_mesh_pt);
424 add_sub_mesh(Surface_mesh_pt);
430 Z2ErrorEstimator* error_estimator_pt=
new Z2ErrorEstimator;
431 dynamic_cast<RefineableCollapsibleChannelMesh<ELEMENT>*
>
432 (Bulk_mesh_pt)->spatial_error_estimator_pt()=error_estimator_pt;
437 unsigned n_element=Bulk_mesh_pt->nelement();
438 for(
unsigned e=0;e<n_element;e++)
441 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
444 el_pt->re_pt() = &Global_Physical_Variables::Re;
447 el_pt->re_st_pt() = &Global_Physical_Variables::ReSt;
455 unsigned n_el=Surface_mesh_pt->nelement();
456 for(
unsigned e=0;e<n_el;e++)
459 NavierStokesTractionElement<ELEMENT> *el_pt =
460 dynamic_cast< NavierStokesTractionElement<ELEMENT>*
>(
461 Surface_mesh_pt->element_pt(e));
464 el_pt->traction_fct_pt() = &Global_Physical_Variables::prescribed_traction;
474 unsigned num_nod= bulk_mesh_pt()->nboundary_node(ibound);
475 for (
unsigned inod=0;inod<num_nod;inod++)
477 for(
unsigned i=0;i<2;i++)
479 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(i);
485 for(
unsigned ib=2;ib<5;ib++)
487 num_nod= bulk_mesh_pt()->nboundary_node(ib);
488 for (
unsigned inod=0;inod<num_nod;inod++)
490 for(
unsigned i=0;i<2;i++)
492 bulk_mesh_pt()->boundary_node_pt(ib, inod)->pin(i);
499 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
500 for (
unsigned inod=0;inod<num_nod;inod++)
502 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
508 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
509 for (
unsigned inod=0;inod<num_nod;inod++)
511 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
521 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
522 unsigned control_nod=num_nod/2;
523 Left_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
527 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
528 control_nod=num_nod/2;
529 Right_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
532 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
542 template <
class ELEMENT>
543 void CollapsibleChannelProblem<ELEMENT>:: doc_solution(DocInfo& doc_info,
544 ofstream& trace_file)
554 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
556 some_file.open(filename);
557 bulk_mesh_pt()->output(some_file,npts);
562 Vector<double> zeta(1);
563 zeta[0]=0.5*Lcollapsible;
564 Vector<double> wall_point(2);
565 Wall_pt->position(zeta,wall_point);
568 trace_file << time_pt()->time() <<
" "
569 << wall_point[1] <<
" "
570 << Left_node_pt->value(0) <<
" "
571 << Right_node_pt->value(0) <<
" "
575 sprintf(filename,
"%s/wall%i.dat",doc_info.directory().c_str(),
577 some_file.open(filename);
579 for (
unsigned i=0;i<nplot;i++)
581 zeta[0]=double(i)/double(nplot-1)*Lcollapsible;
582 Wall_pt->position(zeta,wall_point);
583 some_file << wall_point[0] <<
" "
584 << wall_point[1] << std::endl;
596 template <
class ELEMENT>
597 void CollapsibleChannelProblem<ELEMENT>::create_traction_elements(
598 const unsigned &b, Mesh*
const &bulk_mesh_pt, Mesh*
const &surface_mesh_pt)
601 unsigned n_element = bulk_mesh_pt->nboundary_element(b);
604 for(
unsigned e=0;e<n_element;e++)
607 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>
608 (bulk_mesh_pt->boundary_element_pt(b,e));
611 int face_index = bulk_mesh_pt->face_index_at_boundary(b,e);
614 NavierStokesTractionElement<ELEMENT>* traction_element_pt =
615 new NavierStokesTractionElement<ELEMENT>(bulk_elem_pt,face_index);
618 surface_mesh_pt->add_element_pt(traction_element_pt);
628 template<
class ELEMENT>
629 void CollapsibleChannelProblem<ELEMENT>::
630 delete_traction_elements(Mesh*
const &surface_mesh_pt)
633 unsigned n_element = surface_mesh_pt->nelement();
636 for(
unsigned e=0;e<n_element;e++)
639 delete surface_mesh_pt->element_pt(e);
643 surface_mesh_pt->flush_element_and_node_storage();
652 template <
class ELEMENT>
653 void CollapsibleChannelProblem<ELEMENT>::set_initial_condition()
657 if (time_stepper_pt()->type()!=
"BDF")
659 std::ostringstream error_stream;
661 <<
"Timestepper has to be from the BDF family!\n"
662 <<
"You have specified a timestepper from the "
663 << time_stepper_pt()->type() <<
" family" << std::endl;
665 throw OomphLibError(error_stream.str(),
666 OOMPH_CURRENT_FUNCTION,
667 OOMPH_EXCEPTION_LOCATION);
671 bulk_mesh_pt()->node_update();
674 unsigned num_nod = bulk_mesh_pt()->nnode();
675 for (
unsigned n=0;n<num_nod;n++)
679 x[0]=bulk_mesh_pt()->node_pt(n)->x(0);
680 x[1]=bulk_mesh_pt()->node_pt(n)->x(1);
683 bulk_mesh_pt()->node_pt(n)->set_value(0,6.0*(x[1]/Ly)*(1.0-(x[1]/Ly)));
684 bulk_mesh_pt()->node_pt(n)->set_value(1,0.0);
688 bulk_mesh_pt()->assign_initial_values_impulsive();
699 template <
class ELEMENT>
700 void CollapsibleChannelProblem<ELEMENT>::actions_before_implicit_timestep()
703 bulk_mesh_pt()->node_update();
708 unsigned num_nod=bulk_mesh_pt()->nboundary_node(ibound);
709 for (
unsigned inod=0;inod<num_nod;inod++)
712 Node* node_pt=bulk_mesh_pt()->boundary_node_pt(ibound,inod);
715 FSI_functions::apply_no_slip_on_moving_wall(node_pt);
725 template<
class ELEMENT>
726 void CollapsibleChannelProblem<ELEMENT>::actions_before_adapt()
729 delete_traction_elements(Surface_mesh_pt);
732 rebuild_global_mesh();
740 template<
class ELEMENT>
741 void CollapsibleChannelProblem<ELEMENT>::actions_after_adapt()
745 create_traction_elements(5,Bulk_mesh_pt,Surface_mesh_pt);
748 rebuild_global_mesh();
751 unsigned n_element=Surface_mesh_pt->nelement();
752 for(
unsigned e=0;e<n_element;e++)
755 NavierStokesTractionElement<ELEMENT> *el_pt =
756 dynamic_cast<NavierStokesTractionElement<ELEMENT>*
>(
757 Surface_mesh_pt->element_pt(e));
760 el_pt->traction_fct_pt() = &Global_Physical_Variables::prescribed_traction;
772 int main(
int argc,
char* argv[])
776 CommandLineArgs::setup(argc,argv);
779 unsigned coarsening_factor=1;
780 if (CommandLineArgs::Argc>1)
786 unsigned nup=20/coarsening_factor;
787 unsigned ncollapsible=40/coarsening_factor;
788 unsigned ndown=40/coarsening_factor;
789 unsigned ny=16/coarsening_factor;
793 double lcollapsible=10.0;
798 double amplitude=1.0e-2;
805 Global_Physical_Variables::P_up=12.0*(lup+lcollapsible+ldown);
810 doc_info.set_directory(
"RESLT");
815 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
816 trace_file.open(filename);
819 CollapsibleChannelProblem<RefineableQCrouzeixRaviartElement<2> >
820 problem(nup, ncollapsible, ndown, ny,
821 lup, lcollapsible, ldown, ly,
826 unsigned nsteps_per_period=40;
832 unsigned nstep=nsteps_per_period*nperiod;
833 if (CommandLineArgs::Argc>1)
839 double dt=period/double(nsteps_per_period);
845 problem.time_pt()->time()=t_min;
846 problem.initialise_dt(dt);
847 problem.set_initial_condition();
850 problem.doc_solution(doc_info, trace_file);
857 problem.bulk_mesh_pt()->max_permitted_error()=1.0e-3;
858 problem.bulk_mesh_pt()->min_permitted_error()=1.0e-5;
862 if (CommandLineArgs::Argc>1)
864 problem.bulk_mesh_pt()->max_permitted_error()=1.0e-4;
865 problem.bulk_mesh_pt()->min_permitted_error()=1.0e-6;
874 unsigned max_adapt=10;
877 for (
unsigned istep=0;istep<nstep;istep++)
880 problem.unsteady_newton_solve(dt, max_adapt, first);
884 problem.doc_solution(doc_info, trace_file);
Namespace to define the mapping [0,1] -> [0,1] that re-distributes nodal points across the channel wi...
double squash_fct(const double &s)
Mapping [0,1] -> [0,1] that re-distributes nodal points across the channel width.
double Delta
Boundary layer width.
double Fract_in_BL
Fraction of points in boundary layer.
///////////////////////////////////////////////////////////////// ///////////////////////////////////...