35 #include "navier_stokes.h" 38 #include "meshes/rectangular_quadmesh.h" 42 using namespace oomph;
72 void get_exact_u(
const double& t,
const Vector<double>& x, Vector<double>& u)
76 complex<double> I(0.0,1.0);
78 double omega=2.0*MathematicalConstants::Pi;
81 lambda = I*sqrt(lambda);
85 exp(complex<double>(0.0,omega*t)) *
86 (exp(lambda*complex<double>(0.0,y))-exp(lambda*complex<double>(0.0,-y)))
87 /(exp(I*lambda)-exp(-I*lambda)) );
99 complex<double> I(0.0,1.0);
101 double omega=2.0*MathematicalConstants::Pi;
104 lambda = I*sqrt(lambda);
107 exp(complex<double>(0.0,omega*t)) *
108 (exp(lambda*complex<double>(0.0,y))-exp(lambda*complex<double>(0.0,-y)))
109 /(exp(I*lambda)-exp(-I*lambda)) );
123 template<
class ELEMENT,
class TIMESTEPPER>
131 const double &lx,
const double &ly);
144 unsigned num_nod=mesh_pt()->nboundary_node(ibound);
145 for (
unsigned inod=0;inod<num_nod;inod++)
148 double y=mesh_pt()->boundary_node_pt(ibound,inod)->x(1);
149 double time=time_pt()->time();
154 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(0,soln);
155 mesh_pt()->boundary_node_pt(ibound,inod)->set_value(1,0.0);
161 void unsteady_run(DocInfo& doc_info);
164 void doc_solution(DocInfo& doc_info);
168 void set_initial_condition();
174 const double &pvalue)
177 dynamic_cast<ELEMENT*
>(mesh_pt()->element_pt(e))->
178 fix_pressure(pdof,pvalue);
190 template<
class ELEMENT,
class TIMESTEPPER>
192 (
const unsigned &nx,
const unsigned &ny,
193 const double &lx,
const double& ly)
196 add_time_stepper_pt(
new TIMESTEPPER);
199 bool periodic_in_x=
true;
201 new RectangularQuadMesh<ELEMENT>(nx,ny,lx,ly,periodic_in_x,
207 unsigned num_bound=mesh_pt()->nboundary();
208 for(
unsigned ibound=0;ibound<num_bound;ibound++)
210 unsigned num_nod=mesh_pt()->nboundary_node(ibound);
211 for (
unsigned inod=0;inod<num_nod;inod++)
214 if ((ibound==0)||(ibound==2))
216 mesh_pt()->boundary_node_pt(ibound,inod)->pin(0);
217 mesh_pt()->boundary_node_pt(ibound,inod)->pin(1);
221 else if ((ibound==1)||(ibound==3))
223 mesh_pt()->boundary_node_pt(ibound,inod)->pin(1);
231 unsigned n_el = mesh_pt()->nelement();
232 for(
unsigned e=0;e<n_el;e++)
235 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(mesh_pt()->element_pt(e));
243 fix_pressure(0,0,0.0);
246 cout << assign_eqn_numbers() << std::endl;
256 template<
class ELEMENT,
class TIMESTEPPER>
261 if (time_stepper_pt()->type()!=
"BDF")
263 std::ostringstream error_stream;
264 error_stream <<
"Timestepper has to be from the BDF family!\n" 265 <<
"You have specified a timestepper from the " 266 << time_stepper_pt()->type() <<
" family" << std::endl;
268 throw OomphLibError(error_stream.str(),
269 OOMPH_CURRENT_FUNCTION,
270 OOMPH_EXCEPTION_LOCATION);
274 double backed_up_time=time_pt()->time();
281 Vector<double> soln(2);
285 unsigned num_nod = mesh_pt()->nnode();
289 int nprev_steps=time_stepper_pt()->nprev_values();
290 Vector<double> prev_time(nprev_steps+1);
291 for (
int t=nprev_steps;t>=0;t--)
293 prev_time[t]=time_pt()->time(
unsigned(t));
297 for (
int t=nprev_steps;t>=0;t--)
300 double time=prev_time[t];
301 cout <<
"setting IC at time =" << time << std::endl;
304 for (
unsigned n=0;n<num_nod;n++)
307 x[0]=mesh_pt()->node_pt(n)->x(0);
308 x[1]=mesh_pt()->node_pt(n)->x(1);
314 mesh_pt()->node_pt(n)->set_value(t,0,soln[0]);
315 mesh_pt()->node_pt(n)->set_value(t,1,soln[1]);
319 for (
unsigned i=0;i<2;i++)
321 mesh_pt()->node_pt(n)->x(t,i)=x[i];
327 time_pt()->time()=backed_up_time;
335 template<
class ELEMENT,
class TIMESTEPPER>
345 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
347 some_file.open(filename);
348 mesh_pt()->output(some_file,npts);
351 some_file <<
"TEXT X=2.5,Y=93.6,F=HELV,HU=POINT,C=BLUE,H=26,T=\"time = " 352 << time_pt()->time() <<
"\"";
355 some_file <<
"GEOMETRY X=2.5,Y=98,T=LINE,C=BLUE,LT=0.4" << std::endl;
356 some_file <<
"1" << std::endl;
357 some_file <<
"2" << std::endl;
358 some_file <<
" 0 0" << std::endl;
359 some_file << time_pt()->time()*20.0 <<
" 0" << std::endl;
365 sprintf(filename,
"%s/exact_soln%i.dat",doc_info.directory().c_str(),
367 some_file.open(filename);
368 mesh_pt()->output_fct(some_file,npts,time_pt()->time(),
375 sprintf(filename,
"%s/error%i.dat",doc_info.directory().c_str(),
377 some_file.open(filename);
378 mesh_pt()->compute_error(some_file,
386 cout <<
"error: " << error << std::endl;
387 cout <<
"norm : " << norm << std::endl << std::endl;
390 unsigned n_control=37;
391 Vector<double> x(2), u(2);
392 double time=time_pt()->time();
394 dynamic_cast<ELEMENT*
>(mesh_pt()->element_pt(n_control))->node_pt(1);
395 x[0] = node_pt->x(0);
396 x[1] = node_pt->x(1);
400 Trace_file << time <<
" " 403 << node_pt->value(0) <<
" " 404 << node_pt->value(1) <<
" " 407 << abs(u[0]-node_pt->value(0)) <<
" " 408 << abs(u[1]-node_pt->value(1)) <<
" " 420 template<
class ELEMENT,
class TIMESTEPPER>
426 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
427 Trace_file.open(filename);
430 Trace_file <<
"time" <<
", " 435 <<
"u_exact_1" <<
", " 436 <<
"u_exact_2" <<
", " 439 <<
"L2 error" <<
", " 440 <<
"L2 norm" <<
", " << std::endl;
448 assign_initial_values_impulsive(dt);
449 cout <<
"IC = impulsive start" << std::endl;
456 set_initial_condition();
457 cout <<
"IC = exact solution" << std::endl;
467 cout <<
"validation run" << std::endl;
471 doc_solution(doc_info);
477 for(
unsigned t=1;t<=ntsteps;t++)
479 cout <<
"TIMESTEP " << t << std::endl;
482 unsteady_newton_solve(dt);
485 cout <<
"Time is now " << time_pt()->time() << std::endl;
488 doc_solution(doc_info);
500 int main(
int argc,
char* argv[])
506 cout <<
"No command line arguments specified -- using defaults." 511 cout <<
"Two command line arguments specified:" << std::endl;
519 std::string error_message =
520 "Wrong number of command line arguments. Specify none or two.\n";
522 "Arg1: Long_run_flag [0/1]\n";
524 "Arg2: Impulsive_start_flag [0/1]\n";
526 throw OomphLibError(error_message,
527 OOMPH_CURRENT_FUNCTION,
528 OOMPH_EXCEPTION_LOCATION);
530 cout <<
"Long run flag: " 532 cout <<
"Impulsive start flag: " 559 doc_info.set_directory(
"RESLT_CR");
575 doc_info.set_directory(
"RESLT_TH");
void doc_solution(DocInfo &doc_info)
Doc the solution.
RayleighProblem(const unsigned &nx, const unsigned &ny, const double &lx, const double &ly)
Problem constructor.
void actions_after_newton_solve()
Update after solve is empty.
void get_exact_u(const double &t, const double &y, double &u)
Exact solution of the problem as a scalar.
unsigned Impulsive_start_flag
Flag for impulsive start: Default = start from exact time-periodic solution.
Namespace for exact solution.
void unsteady_run(DocInfo &doc_info)
Run an unsteady simulation.
ofstream Trace_file
Trace file.
unsigned Long_run_flag
Flag for long/short run: Default = perform long run.
void actions_before_implicit_timestep()
Namespace for global parameters.
void get_exact_u(const double &t, const Vector< double > &x, Vector< double > &u)
Exact solution of the problem as a vector.
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.
double ReSt
Womersley = Reynolds times Strouhal.
void actions_before_newton_solve()
int main(int argc, char *argv[])
Driver code for Rayleigh channel problem.
void set_initial_condition()
Set initial condition (incl previous timesteps) according to specified function.
double Re
Reynolds number.