36 #include "navier_stokes.h" 39 #include "meshes/quarter_circle_sector_mesh.h" 43 using namespace oomph;
59 const double& period, Time* time_pt) :
60 GeomObject(1,2),
A(a),
A_hat(a_hat),
T(period), Time_pt(time_pt) {}
67 void position(
const Vector<double>& xi, Vector<double>& r)
const 70 double time=Time_pt->time();
73 double axis=
A+
A_hat*cos(2.0*MathematicalConstants::Pi*time/
T);
74 r[0] = axis*cos(xi[0]);
75 r[1] = (1.0/axis)*sin(xi[0]);
81 void position(
const unsigned& t,
const Vector<double>& xi,
82 Vector<double>& r)
const 85 double time=Time_pt->time(t);
88 double axis=
A+
A_hat*cos(2.0*MathematicalConstants::Pi*time/
T);
89 r[0] = axis*cos(xi[0]);
90 r[1] = (1.0/axis)*sin(xi[0]);
139 void get_exact_u(
const double& t,
const Vector<double>& x, Vector<double>& u)
141 using namespace MathematicalConstants;
147 double a=A+A_hat*cos(2.0*Pi*t/T);
148 double adot=-2.0*A_hat*Pi*sin(2.0*Pi*t/T)/
T;
156 u[2]=(2.0*A_hat*Pi*Pi*Re*(x[0]*x[0]*St*cos(2.0*Pi*t/T)*A +
157 x[0]*x[0]*St*A_hat - x[0]*x[0]*A_hat +
158 x[0]*x[0]*A_hat*cos(2.0*Pi*t/T)*cos(2.0*Pi*t/T) -
159 x[1]*x[1]*St*cos(2.0*Pi*t/T)*A -
160 x[1]*x[1]*St*A_hat - x[1]*x[1]*A_hat +
161 x[1]*x[1]*A_hat*cos(2.0*Pi*t/T)*cos(2.0*Pi*t/T) ))
162 /(T*T*(A*A + 2.0*A*A_hat*cos(2.0*Pi*t/T) +
163 A_hat*A_hat*cos(2.0*Pi*t/T)*cos(2.0*Pi*t/T) ));
181 template<
class ELEMENT,
class TIMESTEPPER>
206 RefineableNavierStokesEquations<2>::
207 unpin_all_pressure_dofs(mesh_pt()->element_pt());
210 RefineableNavierStokesEquations<2>::
211 pin_redundant_nodal_pressures(mesh_pt()->element_pt());
214 fix_pressure(0,0,0.0);
223 mesh_pt()->node_update();
228 unsigned num_nod=mesh_pt()->nboundary_node(ibound);
229 for (
unsigned inod=0;inod<num_nod;inod++)
232 Node* node_pt=mesh_pt()->boundary_node_pt(ibound,inod);
235 FSI_functions::apply_no_slip_on_moving_wall(node_pt);
243 void doc_solution(DocInfo& doc_info);
246 void unsteady_run(DocInfo& doc_info);
249 void set_initial_condition();
255 const double &pvalue)
258 dynamic_cast<ELEMENT*
>(mesh_pt()->element_pt(e))->
259 fix_pressure(pdof,pvalue);
272 template<
class ELEMENT,
class TIMESTEPPER>
277 add_time_stepper_pt(
new TIMESTEPPER);
295 Wall_pt=
new MyEllipse(a,a_hat,period,Problem::time_pt());
300 double xi_hi=MathematicalConstants::Pi/2.0;
305 double fract_mid=0.5;
306 Problem::mesh_pt() =
new RefineableQuarterCircleSectorMesh<ELEMENT>(
307 Wall_pt,xi_lo,fract_mid,xi_hi,time_stepper_pt());
321 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
322 for (
unsigned inod=0;inod<num_nod;inod++)
326 for (
unsigned i=0;i<2;i++)
328 mesh_pt()->boundary_node_pt(ibound,inod)->pin(i);
336 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
337 for (
unsigned inod=0;inod<num_nod;inod++)
341 mesh_pt()->boundary_node_pt(ibound,inod)->pin(1);
349 unsigned num_nod= mesh_pt()->nboundary_node(ibound);
350 for (
unsigned inod=0;inod<num_nod;inod++)
354 mesh_pt()->boundary_node_pt(ibound,inod)->pin(0);
364 unsigned n_element = mesh_pt()->nelement();
368 for(
unsigned i=0;i<n_element;i++)
371 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(mesh_pt()->element_pt(i));
379 RefineableNavierStokesEquations<2>::
380 pin_redundant_nodal_pressures(mesh_pt()->element_pt());
383 fix_pressure(0,0,0.0);
386 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
395 template<
class ELEMENT,
class TIMESTEPPER>
399 double backed_up_time=time_pt()->time();
406 Vector<double> soln(3);
410 unsigned num_nod = mesh_pt()->nnode();
413 int nprev_steps=time_stepper_pt()->nprev_values();
414 Vector<double> prev_time(nprev_steps+1);
415 for (
int itime=nprev_steps;itime>=0;itime--)
417 prev_time[itime]=time_pt()->time(
unsigned(itime));
422 for (
int itime=nprev_steps;itime>=0;itime--)
424 double time=prev_time[itime];
428 time_pt()->time()=time;
430 cout <<
"setting IC at time =" << time << std::endl;
435 mesh_pt()->node_update();
438 for (
unsigned jnod=0;jnod<num_nod;jnod++)
441 x[0]=mesh_pt()->node_pt(jnod)->x(0);
442 x[1]=mesh_pt()->node_pt(jnod)->x(1);
448 mesh_pt()->node_pt(jnod)->set_value(itime,0,soln[0]);
449 mesh_pt()->node_pt(jnod)->set_value(itime,1,soln[1]);
452 for (
unsigned i=0;i<2;i++)
454 mesh_pt()->node_pt(jnod)->x(itime,i)=x[i];
460 time_pt()->time()=backed_up_time;
469 template<
class ELEMENT,
class TIMESTEPPER>
481 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
483 some_file.open(filename);
484 mesh_pt()->output(some_file,npts);
485 some_file <<
"TEXT X=2.5,Y=93.6,F=HELV,HU=POINT,C=BLUE,H=26,T=\"time = " 486 << time_pt()->time() <<
"\"";
487 some_file <<
"GEOMETRY X=2.5,Y=98,T=LINE,C=BLUE,LT=0.4" << std::endl;
488 some_file <<
"1" << std::endl;
489 some_file <<
"2" << std::endl;
490 some_file <<
" 0 0" << std::endl;
491 some_file << time_pt()->time()*20.0 <<
" 0" << std::endl;
495 some_file <<
"ZONE I=2,J=2" << std::endl;
496 some_file <<
"0.0 0.0 -0.65 -0.65 -200.0" << std::endl;
497 some_file <<
"1.15 0.0 -0.65 -0.65 -200.0" << std::endl;
498 some_file <<
"0.0 1.15 -0.65 -0.65 -200.0" << std::endl;
499 some_file <<
"1.15 1.15 -0.65 -0.65 -200.0" << std::endl;
500 some_file <<
"ZONE I=2,J=2" << std::endl;
501 some_file <<
"0.0 0.0 0.65 0.65 300.0" << std::endl;
502 some_file <<
"1.15 0.0 0.65 0.65 300.0" << std::endl;
503 some_file <<
"0.0 1.15 0.65 0.65 300.0" << std::endl;
504 some_file <<
"1.15 1.15 0.65 0.65 300.0" << std::endl;
510 sprintf(filename,
"%s/exact_soln%i.dat",doc_info.directory().c_str(),
512 some_file.open(filename);
513 mesh_pt()->output_fct(some_file,npts,time_pt()->time(),
520 sprintf(filename,
"%s/error%i.dat",doc_info.directory().c_str(),
522 some_file.open(filename);
523 mesh_pt()->compute_error(some_file,
532 cout <<
"error: " << error << std::endl;
533 cout <<
"norm : " << norm << std::endl << std::endl;
538 sprintf(filename,
"%s/Wall%i.dat",doc_info.directory().c_str(),
540 some_file.open(filename);
543 for (
unsigned iplot=0;iplot<nplot;iplot++)
545 Vector<double> xi_wall(1), r_wall(2);
546 xi_wall[0]=0.5*MathematicalConstants::Pi*double(iplot)/double(nplot-1);
547 Wall_pt->position(xi_wall,r_wall);
548 some_file << r_wall[0] <<
" " << r_wall[1] << std::endl;
561 template<
class ELEMENT,
class TIMESTEPPER>
575 set_initial_condition();
581 unsigned nstep = unsigned(t_max/dt);
585 if (CommandLineArgs::Argc>1)
589 cout <<
"validation run" << std::endl;
601 doc_solution(doc_info);
604 for (
unsigned istep=0;istep<nstep;istep++)
606 cout <<
"TIMESTEP " << istep << std::endl;
607 cout <<
"Time is now " << time_pt()->time() << std::endl;
610 unsteady_newton_solve(dt);
613 doc_solution(doc_info);
628 int main(
int argc,
char* argv[])
632 CommandLineArgs::setup(argc,argv);
639 doc_info.set_directory(
"RESLT_CR");
652 doc_info.set_directory(
"RESLT_TH");
OscEllipseProblem()
Constructor.
void actions_after_adapt()
Actions after adaptation, pin relevant pressures.
double T
Period of oscillations.
void unsteady_run(DocInfo &doc_info)
Timestepping loop.
void set_initial_condition()
Set initial condition.
Time * Time_pt
Pointer to time object.
void actions_before_newton_solve()
Update problem specs before solve (empty)
void position(const unsigned &t, const Vector< double > &xi, Vector< double > &r) const
Parametrised position on object: r(xi). Evaluated at previous time level. t=0: current time; t>0: pre...
GeomObject * Wall_pt
Pointer to GeomObject that specifies the domain bondary.
void actions_after_implicit_timestep()
Update the problem specs after timestep (empty)
Navier-Stokes problem in an oscillating ellipse domain.
~OscEllipseProblem()
Destructor (empty)
double ReSt
Womersley = Reynolds times Strouhal.
double T
Period of oscillation.
void actions_before_implicit_timestep()
Update the problem specs before next timestep.
double Re
Reynolds number.
int main(int argc, char *argv[])
void actions_after_newton_solve()
Update the problem specs after solve (empty)
void doc_solution(DocInfo &doc_info)
Doc the solution.
Namepspace for global parameters.
virtual ~MyEllipse()
Destructor: Empty.
Oscillating ellipse Note that cross-sectional area is conserved.
MyEllipse(const double &a, const double &a_hat, const double &period, Time *time_pt)
Constructor: Pass initial x-half axis, amplitude of x-variation, period of oscillation and pointer to...
void get_exact_u(const double &t, const Vector< double > &x, Vector< double > &u)
Exact solution of the problem as a vector containing u,v,p.
double A_hat
x-Half axis amplitude
double A
x-Half axis length
void position(const Vector< double > &xi, Vector< double > &r) const
Current position vector to material point at Lagrangian coordinate xi.
void actions_before_adapt()
Actions before adapt (empty)
double A_hat
Amplitude of variation in x-half axis.
void fix_pressure(const unsigned &e, const unsigned &pdof, const double &pvalue)
Fix pressure in element e at pressure dof pdof and set to pvalue.