32 #include "navier_stokes.h"
35 #include "meshes/quarter_circle_sector_mesh.h"
43 using namespace oomph;
45 using namespace MathematicalConstants;
83 template<
class ELEMENT>
92 FiniteElement::UnsteadyExactSolutionFctPt IC_fct_pt);
117 fluid_mesh_pt()->node_update();
135 unsigned num_nod= fluid_mesh_pt()->nboundary_node(ibound);
136 for (
unsigned inod=0;inod<num_nod;inod++)
138 fluid_mesh_pt()->boundary_node_pt(ibound,inod)->
139 set_auxiliary_node_update_fct_pt(
140 FSI_functions::apply_no_slip_on_moving_wall);
145 dynamic_cast<PseudoBucklingRingElement*
>(Wall_pt)
146 ->set_reference_pressure_pt(fluid_mesh_pt()->element_pt(0)
147 ->internal_data_pt(0));
162 MacroElementNodeUpdateRefineableQuarterCircleSectorMesh<ELEMENT>*
fluid_mesh_pt()
164 return Fluid_mesh_pt;
168 void dump_it(ofstream& dump_file, DocInfo doc_info);
179 FiniteElement::UnsteadyExactSolutionFctPt IC_Fct_pt;
185 MacroElementNodeUpdateRefineableQuarterCircleSectorMesh<ELEMENT>*
Fluid_mesh_pt;
194 Node* Veloc_trace_node_pt;
198 Node* Sarah_veloc_trace_node_pt;
207 template<
class ELEMENT>
209 FiniteElement::UnsteadyExactSolutionFctPt IC_fct_pt) : IC_Fct_pt(IC_fct_pt)
216 add_time_stepper_pt(
new BDF<4>);
223 double eps_buckl=0.1;
224 double ampl_ratio=-0.5;
229 Wall_pt=
new PseudoBucklingRingElement(eps_buckl,ampl_ratio,n_buckl,r_0,T,
235 double xi_hi=2.0*atan(1.0);
238 double fract_mid=0.5;
241 Fluid_mesh_pt=
new MacroElementNodeUpdateRefineableQuarterCircleSectorMesh<ELEMENT>(
242 Wall_pt,xi_lo,fract_mid,xi_hi,time_stepper_pt());
245 Z2ErrorEstimator* error_estimator_pt=
new Z2ErrorEstimator;
246 Fluid_mesh_pt->spatial_error_estimator_pt()=error_estimator_pt;
267 unsigned nnode=
fluid_mesh_pt()->finite_element_pt(0)->nnode();
273 unsigned nnode_1d=
dynamic_cast<ELEMENT*
>(
276 finite_element_pt(0)->node_pt(nnode_1d-1);
281 dynamic_cast<PseudoBucklingRingElement*
>(
Wall_pt)
283 ->internal_data_pt(0));
296 for (
unsigned inod=0;inod<num_nod;inod++)
310 for (
unsigned inod=0;inod<num_nod;inod++)
313 Node* node_pt=
fluid_mesh_pt()->boundary_node_pt(ibound,inod);
317 node_pt->set_auxiliary_node_update_fct_pt(
318 FSI_functions::apply_no_slip_on_moving_wall);
321 for (
unsigned i=0;i<2;i++)
332 for (
unsigned inod=0;inod<num_nod;inod++)
350 for(
unsigned i=0;i<n_element;i++)
353 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(
fluid_mesh_pt()->element_pt(i));
362 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
398 template<
class ELEMENT>
405 dynamic_cast<PseudoBucklingRingElement*
>(Wall_pt)->set_R_0(1.0);
408 double backed_up_time=time_pt()->time();
415 Vector<double> soln(3);
419 unsigned num_nod = fluid_mesh_pt()->nnode();
422 int nprev_steps=time_stepper_pt()->nprev_values();
423 Vector<double> prev_time(nprev_steps+1);
424 for (
int itime=nprev_steps;itime>=0;itime--)
426 prev_time[itime]=time_pt()->time(
unsigned(itime));
431 for (
int itime=nprev_steps;itime>=0;itime--)
433 double time=prev_time[itime];
437 time_pt()->time()=time;
439 cout <<
"setting IC at time =" << time << std::endl;
444 fluid_mesh_pt()->node_update();
447 for (
unsigned jnod=0;jnod<num_nod;jnod++)
451 x[0]=fluid_mesh_pt()->node_pt(jnod)->x(0);
452 x[1]=fluid_mesh_pt()->node_pt(jnod)->x(1);
455 (*IC_Fct_pt)(time,x,soln);
458 for (
unsigned i=0;i<2;i++)
460 fluid_mesh_pt()->node_pt(jnod)->set_value(itime,i,soln[i]);
464 for (
unsigned i=0;i<2;i++)
466 fluid_mesh_pt()->node_pt(jnod)->x(itime,i)=x[i];
472 time_pt()->time()=backed_up_time;
484 template<
class ELEMENT>
488 cout <<
"Doc-ing step " << doc_info.number()
489 <<
" for time " << time_stepper_pt()->time_pt()->time() << std::endl;
501 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
504 some_file.open(filename);
505 unsigned nelem=fluid_mesh_pt()->nelement();
506 for (
unsigned ielem=0;ielem<nelem;ielem++)
508 dynamic_cast<ELEMENT*
>(fluid_mesh_pt()->element_pt(ielem))->
509 full_output(some_file,npts);
516 sprintf(filename,
"%s/Wall%i.dat",doc_info.directory().c_str(),
518 some_file.open(filename);
521 Vector<double > xi_wall(1);
522 Vector<double > r_wall(2);
523 for (
unsigned iplot=0;iplot<nplot;iplot++)
525 xi_wall[0]=0.5*Pi*double(iplot)/double(nplot-1);
526 Wall_pt->position(xi_wall,r_wall);
527 some_file << r_wall[0] <<
" " << r_wall[1] << std::endl;
534 sprintf(filename,
"%s/exact_soln%i.dat",doc_info.directory().c_str(),
536 some_file.open(filename);
537 fluid_mesh_pt()->output_fct(some_file,npts,
538 time_stepper_pt()->time_pt()->time(),
548 Vector<double> xi(1);
549 xi[0]=MathematicalConstants::Pi/2.0;
550 wall_pt()->position(xi,r);
559 double press_int=0.0;
562 nelem=fluid_mesh_pt()->nelement();
564 for (
unsigned ielem=0;ielem<nelem;ielem++)
566 area+=fluid_mesh_pt()->finite_element_pt(ielem)->size();
567 press_int+=
dynamic_cast<ELEMENT*
>(fluid_mesh_pt()->element_pt(ielem))
568 ->pressure_integral();
569 diss+=
dynamic_cast<ELEMENT*
>(fluid_mesh_pt()->element_pt(ielem))->
571 kin_en+=
dynamic_cast<ELEMENT*
>(fluid_mesh_pt()->element_pt(ielem))->
576 double global_kin=4.0*kin_en;
581 fluid_mesh_pt()->get_refinement_levels(min_level,max_level);
585 double time=time_pt()->time();
589 Vector<double> x_sarah(2);
590 Vector<double> soln_sarah(3);
591 x_sarah[0]=Sarah_veloc_trace_node_pt->x(0);
592 x_sarah[1]=Sarah_veloc_trace_node_pt->x(1);
596 Trace_file << time_pt()->time()
600 <<
" " <<
static_cast<PseudoBucklingRingElement*
>(Wall_pt)->r_0()
602 <<
" " << press_int/area
604 <<
" " << diss_asympt
605 <<
" " << Veloc_trace_node_pt->x(0)
606 <<
" " << Veloc_trace_node_pt->x(1)
607 <<
" " << Veloc_trace_node_pt->value(0)
608 <<
" " << Veloc_trace_node_pt->value(1)
609 <<
" " << fluid_mesh_pt()->nelement()
613 <<
" " << fluid_mesh_pt()->nrefinement_overruled()
614 <<
" " << fluid_mesh_pt()->max_error()
615 <<
" " << fluid_mesh_pt()->min_error()
616 <<
" " << fluid_mesh_pt()->max_permitted_error()
617 <<
" " << fluid_mesh_pt()->min_permitted_error()
618 <<
" " << fluid_mesh_pt()->max_keep_unrefined()
619 <<
" " << doc_info.number()
620 <<
" " << Sarah_veloc_trace_node_pt->x(0)
621 <<
" " << Sarah_veloc_trace_node_pt->x(1)
622 <<
" " << Sarah_veloc_trace_node_pt->value(0)
623 <<
" " << Sarah_veloc_trace_node_pt->value(1)
626 <<
" " << soln_sarah[0]
627 <<
" " << soln_sarah[1]
629 <<
static_cast<PseudoBucklingRingElement*
>(Wall_pt)->r_0()-1.0
637 Vector<Tree*> all_element_pt;
638 fluid_mesh_pt()->forest_pt()->
639 stick_all_tree_nodes_into_vector(all_element_pt);
642 Mesh* coarse_mesh_pt =
new Mesh();
646 nelem=all_element_pt.size();
647 for (
unsigned ielem=0;ielem<nelem;ielem++)
649 Tree* el_pt=all_element_pt[ielem];
650 if (el_pt->level()==min_level)
652 coarse_mesh_pt->add_element_pt(el_pt->object_pt());
657 sprintf(filename,
"%s/coarse_soln%i.dat",doc_info.directory().c_str(),
659 some_file.open(filename);
660 nelem=coarse_mesh_pt->nelement();
661 for (
unsigned ielem=0;ielem<nelem;ielem++)
663 dynamic_cast<ELEMENT*
>(coarse_mesh_pt->element_pt(ielem))->
664 full_output(some_file,npts);
669 sprintf(filename,
"%s/restart%i.dat",doc_info.directory().c_str(),
671 some_file.open(filename);
672 dump_it(some_file,doc_info);
685 template<
class ELEMENT>
693 Problem::dump(dump_file);
702 template<
class ELEMENT>
712 Problem::read(restart_file);
729 template<
class ELEMENT>
731 const bool& restarted,
737 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
738 Trace_file.open(filename);
754 fluid_mesh_pt()->max_permitted_error()= 0.5e-2;
755 fluid_mesh_pt()->min_permitted_error()= 0.5e-3;
758 fluid_mesh_pt()->min_refinement_level()=2;
761 fluid_mesh_pt()->max_refinement_level()=6;
765 fluid_mesh_pt()->max_keep_unrefined()=20;
769 unsigned min_refinement_level;
770 unsigned max_refinement_level;
771 fluid_mesh_pt()->get_refinement_levels(min_refinement_level,
772 max_refinement_level);
774 cout <<
"\n Initial mesh: min/max refinement levels: "
775 << min_refinement_level <<
" " << max_refinement_level << std::endl << std::endl;
778 fluid_mesh_pt()->doc_adaptivity_targets(cout);
781 write_trace_file_header();
784 doc_solution(doc_info);
788 doc_info.disable_doc();
799 time_pt()->time()-=time_pt()->dt();
808 double dt=time_pt()->dt();
809 unsteady_newton_solve(dt,max_adapt,first,shift);
812 doc_info.enable_doc();
815 doc_solution(doc_info);
822 for(
unsigned t=2;t<=ntsteps;t++)
826 doc_info.disable_doc();
830 unsteady_newton_solve(dt,max_adapt,first);
833 doc_info.enable_doc();
838 doc_solution(doc_info);
854 template<
class ELEMENT>
859 Trace_file <<
"# err_max " << fluid_mesh_pt()->max_permitted_error() << std::endl;
860 Trace_file <<
"# err_min " << fluid_mesh_pt()->min_permitted_error() << std::endl;
864 Trace_file <<
"# dt " << time_stepper_pt()->time_pt()->dt() << std::endl;
865 Trace_file <<
"# initial # elements " << mesh_pt()->nelement() << std::endl;
866 Trace_file <<
"# min_refinement_level "
867 << fluid_mesh_pt()->min_refinement_level() << std::endl;
868 Trace_file <<
"# max_refinement_level "
869 << fluid_mesh_pt()->max_refinement_level() << std::endl;
873 Trace_file <<
"VARIABLES=\"time\",\"V_c_t_r_l\",\"e_k_i_n\"";
874 Trace_file <<
",\"e_k_i_n_(_a_s_y_m_p_t_)\",\"R_0\",\"Area\"" ;
875 Trace_file <<
",\"Average pressure\",\"Total dissipation (quarter domain)\"";
876 Trace_file <<
",\"Asymptotic dissipation (quarter domain)\"";
877 Trace_file <<
",\"x<sub>1</sub><sup>(track)</sup>\"";
878 Trace_file <<
",\"x<sub>2</sub><sup>(track)</sup>\"";
879 Trace_file <<
",\"u<sub>1</sub><sup>(track)</sup>\"";
880 Trace_file <<
",\"u<sub>2</sub><sup>(track)</sup>\"";
881 Trace_file <<
",\"N<sub>element</sub>\"";
882 Trace_file <<
",\"N<sub>dof</sub>\"";
883 Trace_file <<
",\"max. refinement level\"";
884 Trace_file <<
",\"min. refinement level\"";
885 Trace_file <<
",\"# of elements whose refinement was over-ruled\"";
886 Trace_file <<
",\"max. error\"";
887 Trace_file <<
",\"min. error\"";
888 Trace_file <<
",\"max. permitted error\"";
889 Trace_file <<
",\"min. permitted error\"";
890 Trace_file <<
",\"max. permitted # of unrefined elements\"";
891 Trace_file <<
",\"doc number\"";
892 Trace_file <<
",\"x<sub>1</sub><sup>(track2 FE)</sup>\"";
893 Trace_file <<
",\"x<sub>2</sub><sup>(track2 FE)</sup>\"";
894 Trace_file <<
",\"u<sub>1</sub><sup>(track2 FE)</sup>\"";
895 Trace_file <<
",\"u<sub>2</sub><sup>(track2 FE)</sup>\"";
896 Trace_file <<
",\"x<sub>1</sub><sup>(track2 Sarah)</sup>\"";
897 Trace_file <<
",\"x<sub>2</sub><sup>(track2 Sarah)</sup>\"";
898 Trace_file <<
",\"u<sub>1</sub><sup>(track2 Sarah)</sup>\"";
899 Trace_file <<
",\"u<sub>2</sub><sup>(track2 Sarah)</sup>\"";
900 Trace_file <<
",\"R<sub>0</sub>-1\"";
901 Trace_file << std::endl;
922 int main(
int argc,
char* argv[])
925 CommandLineArgs::setup(argc,argv);
928 unsigned nstep_per_period=40;
932 unsigned nstep=nstep_per_period*nperiod;
933 double dt=1.0/double(nstep_per_period);
943 bool restarted=
false;
946 ifstream* restart_file_pt=0;
950 if (CommandLineArgs::Argc!=2)
952 cout <<
"No restart" << std::endl;
956 problem.refine_uniformly();
957 problem.refine_uniformly();
971 else if (CommandLineArgs::Argc==2)
976 restart_file_pt=
new ifstream(CommandLineArgs::Argv[1],ios_base::in);
977 if (restart_file_pt!=0)
979 cout <<
"Have opened " << CommandLineArgs::Argv[1] <<
980 " for restart. " << std::endl;
984 std::ostringstream error_stream;
985 error_stream <<
"ERROR while trying to open "
986 << CommandLineArgs::Argv[2]
987 <<
" for restart." << std::endl;
989 throw OomphLibError(error_stream.str(),
990 OOMPH_CURRENT_FUNCTION,
991 OOMPH_EXCEPTION_LOCATION);
994 problem.
restart(*restart_file_pt);
999 if (CommandLineArgs::Argc==3)
1002 cout <<
"Only doing nstep steps for validation: " << nstep << std::endl;
1012 doc_info.set_directory(
"RESLT");
1022 if (CommandLineArgs::Argc==3)
1030 RefineableQCrouzeixRaviartElement<2> > >
1034 DocInfo restarted_doc_info;
1037 restarted_doc_info.set_directory(
"RESLT_restarted");
1040 restarted_doc_info.number()=0;
1043 restart_file_pt=
new ifstream(
"RESLT/restart2.dat");
1046 restarted_problem.restart(*restart_file_pt);
1050 bool restarted=
true;
1051 restarted_problem.unsteady_run(nstep,restarted,restarted_doc_info);
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
void unsteady_run(const unsigned &ntsteps, const bool &restarted, DocInfo &doc_info)
Run the time integration for ntsteps steps.
void restart(ifstream &restart_file)
Read problem data.
GeomObject * Wall_pt
Pointer to wall.
void actions_after_adapt()
Update the problem specs after adaptation: Set auxiliary update function that applies no slip on all ...
Node * Sarah_veloc_trace_node_pt
Pointer to node in symmetry plane on coarsest mesh at which velocity is traced.
void actions_after_newton_solve()
Update after solve (empty)
MacroElementNodeUpdateRefineableQuarterCircleSectorMesh< ELEMENT > * Fluid_mesh_pt
Pointer to fluid mesh.
void actions_before_newton_solve()
Update the problem specs before solve (empty)
void doc_solution(DocInfo &doc_info)
Doc the solution.
GeomObject * wall_pt()
Get pointer to wall as geometric object.
void write_trace_file_header()
Write header for trace file.
~OscRingNStProblem()
Destructor (empty)
void actions_before_newton_convergence_check()
Update the problem specs before checking Newton convergence: Update the fluid mesh and re-set velocit...
MacroElementNodeUpdateRefineableQuarterCircleSectorMesh< ELEMENT > * fluid_mesh_pt()
Access function for the fluid mesh.
Mesh * Wall_mesh_pt
Pointer to wall mesh (contains only a single GeneralisedElement)
void set_initial_condition()
Set initial condition (incl previous timesteps) according to specified function.
OscRingNStProblem(const double &dt, FiniteElement::UnsteadyExactSolutionFctPt IC_fct_pt)
Constructor: Pass timestep and function pointer to the solution that provides the initial conditions ...
AlgebraicRefineableQuarterCircleSectorMesh< ELEMENT > * fluid_mesh_pt()
Access function for the fluid mesh.
Node * Veloc_trace_node_pt
Pointer to node on coarsest mesh on which velocity is traced.
void dump_it(ofstream &dump_file, DocInfo doc_info)
Dump problem data.
AlgebraicRefineableQuarterCircleSectorMesh< ELEMENT > * Fluid_mesh_pt
Pointer to fluid mesh.
Namespace for physical parameters.
double ReSt
Reynolds x Strouhal number.
double Re
Reynolds number.
double Kin_energy_sarah(double t)
void full_exact_soln(const double &time, const Vector< double > &x, Vector< double > &soln)
Full exact solution: x,y,u,v,p,du/dt,dv/dt,diss.
void exact_soln(const double &time, const Vector< double > &x, Vector< double > &soln)
Exact solution: x,y,u,v,p.
double Total_Diss_sarah(double t)
int main(int argc, char *argv[])
///////////////////////////////////////////////////////////////////// ///////////////////////////////...