32 #include "navier_stokes.h"
39 using namespace oomph;
117 class OscillatingWall :
public GeomObject
126 OscillatingWall(
const double& h,
const double& x_left,
const double& l,
127 const double& a,
const double& period, Time* time_pt) :
128 GeomObject(1,2), H(h), Length(l), X_left(x_left), A(a), B(0.0), T(period),
136 double& amplitude(){
return A;}
139 double& period(){
return T;}
143 void position(
const unsigned& t,
const Vector<double>&zeta,
144 Vector<double>& r)
const
146 using namespace MathematicalConstants;
150 if (Time_pt->time(t)<T)
152 ramp=0.5*(1.0-cos(Pi*Time_pt->time(t)/T));
156 r[0] = zeta[0]+X_left
157 -B*A*sin(2.0*3.14159*zeta[0]/Length)*
158 sin(2.0*Pi*(Time_pt->time(t))/T)*ramp;
160 r[1] = H+A*((Length-zeta[0])*zeta[0])/pow(0.5*Length,2)*
161 sin(2.0*Pi*(Time_pt->time(t))/T)*ramp;
167 void position(
const Vector<double>&zeta, Vector<double>& r)
const
169 position (0, zeta, r);
173 unsigned ngeom_data()
const {
return 0;}
206 namespace Global_Physical_Variables
218 void prescribed_traction(
const double& t,
219 const Vector<double>& x,
220 const Vector<double>& n,
221 Vector<double>& traction)
235 template <
class ELEMENT>
236 class CollapsibleChannelProblem :
public Problem
244 CollapsibleChannelProblem(
const unsigned& nup,
245 const unsigned& ncollapsible,
246 const unsigned& ndown,
249 const double& lcollapsible,
252 const double& amplitude,
253 const double& period);
256 ~CollapsibleChannelProblem() {}
289 void actions_before_newton_solve(){}
292 void actions_after_newton_solve(){}
295 void actions_before_implicit_timestep();
298 void actions_before_adapt();
301 void actions_after_adapt();
304 void set_initial_condition();
307 void doc_solution(DocInfo& doc_info, ofstream& trace_file);
313 void create_traction_elements(
const unsigned &b,
314 Mesh*
const &bulk_mesh_pt,
315 Mesh*
const &surface_mesh_pt);
318 void delete_traction_elements(Mesh*
const &surface_mesh_pt);
325 unsigned Ncollapsible;
346 OscillatingWall* Wall_pt;
353 Mesh* Surface_mesh_pt;
369 template <
class ELEMENT>
370 CollapsibleChannelProblem<ELEMENT>::CollapsibleChannelProblem(
372 const unsigned& ncollapsible,
373 const unsigned& ndown,
376 const double& lcollapsible,
379 const double& amplitude,
380 const double& period)
384 Ncollapsible=ncollapsible;
390 Lcollapsible=lcollapsible;
396 Problem::Max_residuals=10000;
401 add_time_stepper_pt(
new BDF<2>);
405 double length=lcollapsible;
409 Wall_pt=
new OscillatingWall(height, x_left, length, amplitude, period,
416 nup, ncollapsible, ndown, ny,
417 lup, lcollapsible, ldown, ly,
419 #ifdef USE_BL_SQUASH_FCT
428 nup, ncollapsible, ndown, ny,
429 lup, lcollapsible, ldown, ly,
431 #ifdef USE_BL_SQUASH_FCT
442 Surface_mesh_pt =
new Mesh;
446 create_traction_elements(5,Bulk_mesh_pt,Surface_mesh_pt);
449 add_sub_mesh(Bulk_mesh_pt);
450 add_sub_mesh(Surface_mesh_pt);
459 Z2ErrorEstimator* error_estimator_pt=
new Z2ErrorEstimator;
461 (Bulk_mesh_pt)->spatial_error_estimator_pt()=error_estimator_pt;
467 unsigned n_element=Bulk_mesh_pt->nelement();
468 for(
unsigned e=0;e<n_element;e++)
471 ELEMENT* el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
474 el_pt->re_pt() = &Global_Physical_Variables::Re;
477 el_pt->re_st_pt() = &Global_Physical_Variables::ReSt;
485 unsigned n_el=Surface_mesh_pt->nelement();
486 for(
unsigned e=0;e<n_el;e++)
489 NavierStokesTractionElement<ELEMENT> *el_pt =
490 dynamic_cast< NavierStokesTractionElement<ELEMENT>*
>(
491 Surface_mesh_pt->element_pt(e));
494 el_pt->traction_fct_pt() = &Global_Physical_Variables::prescribed_traction;
504 unsigned num_nod= bulk_mesh_pt()->nboundary_node(ibound);
505 for (
unsigned inod=0;inod<num_nod;inod++)
507 for(
unsigned i=0;i<2;i++)
509 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(i);
515 for(
unsigned ib=2;ib<5;ib++)
517 num_nod= bulk_mesh_pt()->nboundary_node(ib);
518 for (
unsigned inod=0;inod<num_nod;inod++)
520 for(
unsigned i=0;i<2;i++)
522 bulk_mesh_pt()->boundary_node_pt(ib, inod)->pin(i);
529 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
530 for (
unsigned inod=0;inod<num_nod;inod++)
532 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
538 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
539 for (
unsigned inod=0;inod<num_nod;inod++)
541 bulk_mesh_pt()->boundary_node_pt(ibound, inod)->pin(1);
551 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
552 unsigned control_nod=num_nod/2;
553 Left_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
557 num_nod= bulk_mesh_pt()->nboundary_node(ibound);
558 control_nod=num_nod/2;
559 Right_node_pt= bulk_mesh_pt()->boundary_node_pt(ibound, control_nod);
562 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
572 template <
class ELEMENT>
573 void CollapsibleChannelProblem<ELEMENT>:: doc_solution(DocInfo& doc_info,
574 ofstream& trace_file)
584 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
586 some_file.open(filename);
587 bulk_mesh_pt()->output(some_file,npts);
592 Vector<double> zeta(1);
593 zeta[0]=0.5*Lcollapsible;
594 Vector<double> wall_point(2);
595 Wall_pt->position(zeta,wall_point);
598 trace_file << time_pt()->time() <<
" "
599 << wall_point[1] <<
" "
600 << Left_node_pt->value(0) <<
" "
601 << Right_node_pt->value(0) <<
" "
605 sprintf(filename,
"%s/wall%i.dat",doc_info.directory().c_str(),
607 some_file.open(filename);
609 for (
unsigned i=0;i<nplot;i++)
611 zeta[0]=double(i)/double(nplot-1)*Lcollapsible;
612 Wall_pt->position(zeta,wall_point);
613 some_file << wall_point[0] <<
" "
614 << wall_point[1] << std::endl;
626 template <
class ELEMENT>
627 void CollapsibleChannelProblem<ELEMENT>::create_traction_elements(
628 const unsigned &b, Mesh*
const &bulk_mesh_pt, Mesh*
const &surface_mesh_pt)
631 unsigned n_element = bulk_mesh_pt->nboundary_element(b);
634 for(
unsigned e=0;e<n_element;e++)
637 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>
638 (bulk_mesh_pt->boundary_element_pt(b,e));
641 int face_index = bulk_mesh_pt->face_index_at_boundary(b,e);
644 NavierStokesTractionElement<ELEMENT>* traction_element_pt =
645 new NavierStokesTractionElement<ELEMENT>(bulk_elem_pt,face_index);
648 surface_mesh_pt->add_element_pt(traction_element_pt);
658 template<
class ELEMENT>
659 void CollapsibleChannelProblem<ELEMENT>::
660 delete_traction_elements(Mesh*
const &surface_mesh_pt)
663 unsigned n_element = surface_mesh_pt->nelement();
666 for(
unsigned e=0;e<n_element;e++)
669 delete surface_mesh_pt->element_pt(e);
673 surface_mesh_pt->flush_element_and_node_storage();
683 template <
class ELEMENT>
684 void CollapsibleChannelProblem<ELEMENT>::set_initial_condition()
688 if (time_stepper_pt()->type()!=
"BDF")
690 std::ostringstream error_stream;
692 <<
"Timestepper has to be from the BDF family!\n"
693 <<
"You have specified a timestepper from the "
694 << time_stepper_pt()->type() <<
" family" << std::endl;
696 throw OomphLibError(error_stream.str(),
697 OOMPH_CURRENT_FUNCTION,
698 OOMPH_EXCEPTION_LOCATION);
702 bulk_mesh_pt()->node_update();
705 unsigned num_nod = bulk_mesh_pt()->nnode();
706 for (
unsigned n=0;n<num_nod;n++)
710 x[0]=bulk_mesh_pt()->node_pt(n)->x(0);
711 x[1]=bulk_mesh_pt()->node_pt(n)->x(1);
714 bulk_mesh_pt()->node_pt(n)->set_value(0,6.0*(x[1]/Ly)*(1.0-(x[1]/Ly)));
715 bulk_mesh_pt()->node_pt(n)->set_value(1,0.0);
719 bulk_mesh_pt()->assign_initial_values_impulsive();
730 template <
class ELEMENT>
731 void CollapsibleChannelProblem<ELEMENT>::actions_before_implicit_timestep()
734 bulk_mesh_pt()->node_update();
739 unsigned num_nod=bulk_mesh_pt()->nboundary_node(ibound);
740 for (
unsigned inod=0;inod<num_nod;inod++)
743 Node* node_pt=bulk_mesh_pt()->boundary_node_pt(ibound,inod);
746 FSI_functions::apply_no_slip_on_moving_wall(node_pt);
756 template<
class ELEMENT>
757 void CollapsibleChannelProblem<ELEMENT>::actions_before_adapt()
760 delete_traction_elements(Surface_mesh_pt);
763 rebuild_global_mesh();
771 template<
class ELEMENT>
772 void CollapsibleChannelProblem<ELEMENT>::actions_after_adapt()
776 create_traction_elements(5,Bulk_mesh_pt,Surface_mesh_pt);
779 rebuild_global_mesh();
783 unsigned n_element=Surface_mesh_pt->nelement();
784 for(
unsigned e=0;e<n_element;e++)
787 NavierStokesTractionElement<ELEMENT> *el_pt =
788 dynamic_cast<NavierStokesTractionElement<ELEMENT>*
>(
789 Surface_mesh_pt->element_pt(e));
792 el_pt->traction_fct_pt() = &Global_Physical_Variables::prescribed_traction;
804 int main(
int argc,
char* argv[])
808 CommandLineArgs::setup(argc,argv);
811 unsigned coarsening_factor=1;
812 if (CommandLineArgs::Argc>1)
818 unsigned nup=20/coarsening_factor;
819 unsigned ncollapsible=40/coarsening_factor;
820 unsigned ndown=40/coarsening_factor;
821 unsigned ny=16/coarsening_factor;
825 double lcollapsible=10.0;
830 double amplitude=1.0e-2;
837 Global_Physical_Variables::P_up=12.0*(lup+lcollapsible+ldown);
842 doc_info.set_directory(
"RESLT");
847 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
848 trace_file.open(filename);
854 CollapsibleChannelProblem<AlgebraicElement<RefineableQCrouzeixRaviartElement<2> > >
855 problem(nup, ncollapsible, ndown, ny,
856 lup, lcollapsible, ldown, ly,
862 CollapsibleChannelProblem<AlgebraicElement<QCrouzeixRaviartElement<2> > >
863 problem(nup, ncollapsible, ndown, ny,
864 lup, lcollapsible, ldown, ly,
873 unsigned nsteps_per_period=40;
879 unsigned nstep=nsteps_per_period*nperiod;
880 if (CommandLineArgs::Argc>1)
886 double dt=period/double(nsteps_per_period);
892 problem.time_pt()->time()=t_min;
893 problem.initialise_dt(dt);
894 problem.set_initial_condition();
897 problem.doc_solution(doc_info, trace_file);
905 problem.bulk_mesh_pt()->max_permitted_error()=1.0e-3;
906 problem.bulk_mesh_pt()->min_permitted_error()=1.0e-5;
910 if (CommandLineArgs::Argc>1)
912 problem.bulk_mesh_pt()->max_permitted_error()=1.0e-4;
913 problem.bulk_mesh_pt()->min_permitted_error()=1.0e-6;
921 unsigned max_adapt=10;
926 for (
unsigned istep=0;istep<nstep;istep++)
932 problem.unsteady_newton_solve(dt, max_adapt, first);
938 problem.unsteady_newton_solve(dt);
943 problem.doc_solution(doc_info, trace_file);
Collapsible channel mesh with algebraic node update.
//////////////////////////////////////////////////////////////////////// ////////////////////////////...
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.
///////////////////////////////////////////////////////////////// ///////////////////////////////////...