36 #include "navier_stokes.h"    39 #include "meshes/quarter_circle_sector_mesh.h"    47 using namespace oomph;
    87 template<
class ELEMENT>
    96                    FiniteElement::UnsteadyExactSolutionFctPt IC_fct_pt);
   121   fluid_mesh_pt()->node_update(); 
   139     unsigned num_nod= fluid_mesh_pt()->nboundary_node(ibound);
   140     for (
unsigned inod=0;inod<num_nod;inod++)
   142       fluid_mesh_pt()->boundary_node_pt(ibound,inod)->
   143        set_auxiliary_node_update_fct_pt(
   144         FSI_functions::apply_no_slip_on_moving_wall); 
   149    dynamic_cast<PseudoBucklingRingElement*
>(Wall_pt)
   150     ->set_reference_pressure_pt(fluid_mesh_pt()->element_pt(0)
   151                                 ->internal_data_pt(0));
   155  void unsteady_run(
const unsigned &ntsteps, 
const bool& restarted,
   160  void set_initial_condition();
   163  void doc_solution(DocInfo& doc_info);
   166  MacroElementNodeUpdateRefineableQuarterCircleSectorMesh<ELEMENT>* 
fluid_mesh_pt()
   168    return Fluid_mesh_pt; 
   172  void dump_it(ofstream& dump_file, DocInfo doc_info);
   175  void restart(ifstream& restart_file);
   180  void write_trace_file_header();
   183  FiniteElement::UnsteadyExactSolutionFctPt IC_Fct_pt;
   189  MacroElementNodeUpdateRefineableQuarterCircleSectorMesh<ELEMENT>* 
Fluid_mesh_pt;
   198  Node* Veloc_trace_node_pt;
   202  Node* Sarah_veloc_trace_node_pt;
   211 template<
class ELEMENT>
   213 FiniteElement::UnsteadyExactSolutionFctPt IC_fct_pt) : IC_Fct_pt(IC_fct_pt)
   220  add_time_stepper_pt(
new BDF<4>);
   227  double eps_buckl=0.1;  
   228  double ampl_ratio=-0.5;  
   233  Wall_pt=
new PseudoBucklingRingElement(eps_buckl,ampl_ratio,n_buckl,r_0,T,
   239  double xi_hi=2.0*atan(1.0);
   242  double fract_mid=0.5;
   245  Fluid_mesh_pt=
new MacroElementNodeUpdateRefineableQuarterCircleSectorMesh<ELEMENT>(
   246   Wall_pt,xi_lo,fract_mid,xi_hi,time_stepper_pt());
   249  Z2ErrorEstimator* error_estimator_pt=
new Z2ErrorEstimator;
   250  Fluid_mesh_pt->spatial_error_estimator_pt()=error_estimator_pt;
   260  Wall_mesh_pt->add_element_pt(dynamic_cast<GeneralisedElement*>(Wall_pt));
   271  unsigned nnode=
fluid_mesh_pt()->finite_element_pt(0)->nnode();
   277  unsigned nnode_1d=
dynamic_cast<ELEMENT*
>(
   280   finite_element_pt(0)->node_pt(nnode_1d-1);
   285  dynamic_cast<PseudoBucklingRingElement*
>(
Wall_pt)
   287                               ->internal_data_pt(0));
   300    for (
unsigned inod=0;inod<num_nod;inod++)
   314    for (
unsigned inod=0;inod<num_nod;inod++)
   317      Node* node_pt=
fluid_mesh_pt()->boundary_node_pt(ibound,inod);
   321      node_pt->set_auxiliary_node_update_fct_pt(
   322       FSI_functions::apply_no_slip_on_moving_wall);
   325      for (
unsigned i=0;i<2;i++)
   336    for (
unsigned inod=0;inod<num_nod;inod++)
   354  for(
unsigned i=0;i<n_element;i++)
   357    ELEMENT *el_pt = 
dynamic_cast<ELEMENT*
>(
fluid_mesh_pt()->element_pt(i));
   366  cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl; 
   402 template<
class ELEMENT>
   409  dynamic_cast<PseudoBucklingRingElement*
>(
Wall_pt)->set_R_0(1.0); 
   412  double backed_up_time=time_pt()->time();
   419  Vector<double> soln(3);
   426  int nprev_steps=time_stepper_pt()->nprev_values();
   427  Vector<double> prev_time(nprev_steps+1);
   428  for (
int itime=nprev_steps;itime>=0;itime--)
   430    prev_time[itime]=time_pt()->time(
unsigned(itime));
   435  for (
int itime=nprev_steps;itime>=0;itime--)
   437    double time=prev_time[itime];
   441    time_pt()->time()=time;
   443    cout << 
"setting IC at time =" << time << std::endl;
   451    for (
unsigned jnod=0;jnod<num_nod;jnod++)
   459      (*IC_Fct_pt)(time,x,soln);
   462      for (
unsigned i=0;i<2;i++)
   468      for (
unsigned i=0;i<2;i++)
   476  time_pt()->time()=backed_up_time;
   488 template<
class ELEMENT>
   492  cout << 
"Doc-ing step " <<  doc_info.number()
   493       << 
" for time " << time_stepper_pt()->time_pt()->time() << std::endl;
   505  sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
   508  some_file.open(filename);
   510  for (
unsigned ielem=0;ielem<nelem;ielem++)
   513     full_output(some_file,npts);
   520  sprintf(filename,
"%s/Wall%i.dat",doc_info.directory().c_str(),
   522  some_file.open(filename);
   525  Vector<double > xi_wall(1);
   526  Vector<double > r_wall(2);
   527   for (
unsigned iplot=0;iplot<nplot;iplot++)
   529     xi_wall[0]=0.5*Pi*double(iplot)/double(nplot-1);
   530     Wall_pt->position(xi_wall,r_wall);
   531     some_file << r_wall[0] << 
" " << r_wall[1] << std::endl;
   538  sprintf(filename,
"%s/exact_soln%i.dat",doc_info.directory().c_str(),
   540  some_file.open(filename);
   542                        time_stepper_pt()->time_pt()->time(), 
   552  Vector<double> xi(1);
   553  xi[0]=MathematicalConstants::Pi/2.0;
   563  double press_int=0.0;
   568  for (
unsigned ielem=0;ielem<nelem;ielem++)
   571    press_int+=
dynamic_cast<ELEMENT*
>(
fluid_mesh_pt()->element_pt(ielem))
   572     ->pressure_integral();
   573    diss+=
dynamic_cast<ELEMENT*
>(
fluid_mesh_pt()->element_pt(ielem))->
   575    kin_en+=
dynamic_cast<ELEMENT*
>(
fluid_mesh_pt()->element_pt(ielem))->
   580  double global_kin=4.0*kin_en;
   589  double time=time_pt()->time();
   593  Vector<double> x_sarah(2);
   594  Vector<double> soln_sarah(3);
   604             << 
" " << 
static_cast<PseudoBucklingRingElement*
>(
Wall_pt)->r_0()
   606             << 
" " << press_int/area 
   608             << 
" " << diss_asympt
   623             << 
" " << doc_info.number()
   630             << 
" " << soln_sarah[0]
   631             << 
" " << soln_sarah[1]
   633             << 
static_cast<PseudoBucklingRingElement*
>(
Wall_pt)->r_0()-1.0
   641  Vector<Tree*> all_element_pt;
   643   stick_all_tree_nodes_into_vector(all_element_pt);
   646  Mesh* coarse_mesh_pt = 
new Mesh();
   650  nelem=all_element_pt.size();
   651  for (
unsigned ielem=0;ielem<nelem;ielem++)
   653    Tree* el_pt=all_element_pt[ielem];
   654    if (el_pt->level()==min_level)
   656      coarse_mesh_pt->add_element_pt(el_pt->object_pt());
   661  sprintf(filename,
"%s/coarse_soln%i.dat",doc_info.directory().c_str(),
   663  some_file.open(filename);
   664  nelem=coarse_mesh_pt->nelement();
   665  for (
unsigned ielem=0;ielem<nelem;ielem++)
   667    dynamic_cast<ELEMENT*
>(coarse_mesh_pt->element_pt(ielem))->
   668     full_output(some_file,npts);
   673  sprintf(filename,
"%s/restart%i.dat",doc_info.directory().c_str(),
   675  some_file.open(filename);
   689 template<
class ELEMENT>
   697  Problem::dump(dump_file);
   706 template<
class ELEMENT>
   716  Problem::read(restart_file);
   733 template<
class ELEMENT>
   735                                               const bool& restarted,
   741  sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
   773  unsigned min_refinement_level;
   774  unsigned max_refinement_level;
   776                                         max_refinement_level);
   778  cout << 
"\n Initial mesh: min/max refinement levels: "    779       << min_refinement_level << 
" " << max_refinement_level << std::endl << std::endl;
   792  doc_info.disable_doc();
   803    time_pt()->time()-=time_pt()->dt();
   812  double dt=time_pt()->dt();
   813  unsteady_newton_solve(dt,max_adapt,first,shift);
   816  doc_info.enable_doc();
   826  for(
unsigned t=2;t<=ntsteps;t++)
   830    doc_info.disable_doc();
   834    unsteady_newton_solve(dt,max_adapt,first);
   837    doc_info.enable_doc();
   858 template<
class ELEMENT>
   868  Trace_file << 
"# dt " << time_stepper_pt()->time_pt()->dt() << std::endl;
   869  Trace_file << 
"# initial # elements " << mesh_pt()->nelement() << std::endl;
   877  Trace_file << 
"VARIABLES=\"time\",\"V_c_t_r_l\",\"e_k_i_n\"";
   878  Trace_file << 
",\"e_k_i_n_(_a_s_y_m_p_t_)\",\"R_0\",\"Area\"" ;
   879  Trace_file << 
",\"Average pressure\",\"Total dissipation (quarter domain)\"";
   880  Trace_file << 
",\"Asymptotic dissipation (quarter domain)\"";
   881  Trace_file << 
",\"x<sub>1</sub><sup>(track)</sup>\"";
   882  Trace_file << 
",\"x<sub>2</sub><sup>(track)</sup>\"";
   883  Trace_file << 
",\"u<sub>1</sub><sup>(track)</sup>\"";
   884  Trace_file << 
",\"u<sub>2</sub><sup>(track)</sup>\"";
   889  Trace_file << 
",\"# of elements whose refinement was over-ruled\"";
   894  Trace_file << 
",\"max. permitted # of unrefined elements\"";
   896  Trace_file << 
",\"x<sub>1</sub><sup>(track2 FE)</sup>\"";
   897  Trace_file << 
",\"x<sub>2</sub><sup>(track2 FE)</sup>\"";
   898  Trace_file << 
",\"u<sub>1</sub><sup>(track2 FE)</sup>\"";
   899  Trace_file << 
",\"u<sub>2</sub><sup>(track2 FE)</sup>\"";
   900  Trace_file << 
",\"x<sub>1</sub><sup>(track2 Sarah)</sup>\"";
   901  Trace_file << 
",\"x<sub>2</sub><sup>(track2 Sarah)</sup>\"";
   902  Trace_file << 
",\"u<sub>1</sub><sup>(track2 Sarah)</sup>\"";
   903  Trace_file << 
",\"u<sub>2</sub><sup>(track2 Sarah)</sup>\"";
   926 int main(
int argc, 
char* argv[])
   929  CommandLineArgs::setup(argc,argv);
   932  unsigned nstep_per_period=40; 
   936  unsigned nstep=nstep_per_period*nperiod;  
   937  double dt=1.0/double(nstep_per_period);
   947  bool restarted=
false;
   950  ifstream* restart_file_pt=0;
   954  if (CommandLineArgs::Argc!=2)
   956    cout << 
"No restart" << std::endl;
   960    problem.refine_uniformly();
   961    problem.refine_uniformly();
   975  else if (CommandLineArgs::Argc==2)
   980    restart_file_pt=
new ifstream(CommandLineArgs::Argv[1],ios_base::in);
   981    if (restart_file_pt!=0)
   983      cout << 
"Have opened " << CommandLineArgs::Argv[1] << 
   984       " for restart. " << std::endl;
   988      std::ostringstream error_stream;
   989      error_stream << 
"ERROR while trying to open "    990                   << CommandLineArgs::Argv[2] 
   991                   << 
" for restart." << std::endl;
   993      throw OomphLibError(error_stream.str(),
   994                          OOMPH_CURRENT_FUNCTION,
   995                          OOMPH_EXCEPTION_LOCATION);
   998    problem.
restart(*restart_file_pt);
  1003  if (CommandLineArgs::Argc==3)
  1006     cout << 
"Only doing nstep steps for validation: " << nstep << std::endl;
  1016  doc_info.set_directory(
"RESLT"); 
  1026  if (CommandLineArgs::Argc==3)
  1034     RefineableQCrouzeixRaviartElement<2> > >
  1038    DocInfo restarted_doc_info;
  1041    restarted_doc_info.set_directory(
"RESLT_restarted"); 
  1044    restarted_doc_info.number()=0;
  1047    restart_file_pt=
new ifstream(
"RESLT/restart2.dat");
  1050    restarted_problem.restart(*restart_file_pt);
  1054    bool restarted=
true;
  1055    restarted_problem.unsteady_run(nstep,restarted,restarted_doc_info);
 OscRingNStProblem(const double &dt, FiniteElement::UnsteadyExactSolutionFctPt IC_fct_pt)
Constructor: Pass timestep and function pointer to the solution that provides the initial conditions ...
void actions_after_newton_solve()
Update after solve (empty) 
void doc_solution(DocInfo &doc_info)
Doc the solution. 
AlgebraicRefineableQuarterCircleSectorMesh< ELEMENT > * fluid_mesh_pt()
Access function for the fluid mesh. 
Node * Sarah_veloc_trace_node_pt
Pointer to node in symmetry plane on coarsest mesh at which velocity is traced. 
void unsteady_run(const unsigned &ntsteps, const bool &restarted, DocInfo &doc_info)
Run the time integration for ntsteps steps. 
void dump_it(ofstream &dump_file, DocInfo doc_info)
Dump problem data. 
double ReSt
Reynolds x Strouhal number. 
void set_initial_condition()
Set initial condition (incl previous timesteps) according to specified function. 
void actions_before_newton_solve()
Update the problem specs before solve (empty) 
int main(int argc, char *argv[])
double Re
Reynolds number. 
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 restart(ifstream &restart_file)
Read problem data. 
void actions_after_adapt()
Update the problem specs after adaptation: Set auxiliary update function that applies no slip on all ...
GeomObject * Wall_pt
Pointer to wall. 
Namespace for physical parameters. 
ofstream Trace_file
Trace file. 
~OscRingNStProblem()
Destructor (empty) 
MacroElementNodeUpdateRefineableQuarterCircleSectorMesh< ELEMENT > * fluid_mesh_pt()
Access function for the fluid mesh. 
AlgebraicRefineableQuarterCircleSectorMesh< ELEMENT > * Fluid_mesh_pt
Pointer to fluid mesh. 
MacroElementNodeUpdateRefineableQuarterCircleSectorMesh< ELEMENT > * Fluid_mesh_pt
Pointer to fluid mesh. 
double Total_Diss_sarah(double t)
GeomObject * wall_pt()
Get pointer to wall as geometric object. 
void write_trace_file_header()
Write header for trace file. 
Mesh * Wall_mesh_pt
Pointer to wall mesh (contains only a single GeneralisedElement) 
Node * Veloc_trace_node_pt
Pointer to node on coarsest mesh on which velocity is traced. 
void actions_before_newton_convergence_check()
Update the problem specs before checking Newton convergence: Update the fluid mesh and re-set velocit...
void exact_soln(const double &time, const Vector< double > &x, Vector< double > &soln)
Exact solution: x,y,u,v,p. 
double Kin_energy_sarah(double t)