41#include "navier_stokes.h"
43#include "fluid_interface.h"
44#include "meshes/simple_rectangular_quadmesh.h"
66 Vector<double>
G(2,0.0);
85 Vector<double> &normal)
92 Vector<double> &normal)
97 unsigned n_dim = normal.size();
98 for(
unsigned i=0;i<n_dim;++i) {normal[i] *= -1.0;}
107 const Vector<double> &n,
108 Vector<double> &traction)
110 traction[0] =
ReInvFr*
G[1]*(1.0 - x[1]);
116 const Vector<double> &n,
117 Vector<double> &traction)
119 traction[0] = -
ReInvFr*
G[1]*(1.0 - x[1]);
137template<
class ELEMENT,
class INTERFACE_ELEMENT>
162 const double &length) :
169 void timestep(
const double &dt,
const unsigned &n_tsteps);
176 double time = this->time_pt()->time();
179 double epsilon = 0.01;
181 unsigned n_node = this->Bulk_mesh_pt->nboundary_node(0);
182 for(
unsigned n=0;n<n_node;n++)
184 Node* nod_pt = this->Bulk_mesh_pt->boundary_node_pt(0,n);
186 double value = sin(arg)*epsilon*time*exp(-time);
187 nod_pt->set_value(1,value);
201 unsigned n_boundary_element =
Bulk_mesh_pt->nboundary_element(b);
203 for(
unsigned e=0;e<n_boundary_element;e++)
205 NavierStokesTractionElement<ELEMENT> *surface_element_pt =
206 new NavierStokesTractionElement<ELEMENT>
212 surface_element_pt->traction_fct_pt() =
221 unsigned n_boundary_element =
Bulk_mesh_pt->nboundary_element(b);
223 for(
unsigned e=0;e<n_boundary_element;e++)
225 NavierStokesTractionElement<ELEMENT> *surface_element_pt =
226 new NavierStokesTractionElement<ELEMENT>
232 surface_element_pt->traction_fct_pt() =
247 unsigned n_boundary_element =
Bulk_mesh_pt->nboundary_element(b);
249 for(
unsigned e=0;e<n_boundary_element;e++)
251 INTERFACE_ELEMENT *surface_element_pt =
252 new INTERFACE_ELEMENT
258 surface_element_pt->ca_pt() =
266 FluidInterfaceBoundingElement* point_element_pt =
267 surface_element_pt->make_bounding_element(-1);
273 point_element_pt->wall_unit_normal_fct_pt() =
276 point_element_pt->set_contact_angle(
283 if(e==n_boundary_element-1)
285 FluidInterfaceBoundingElement* point_element_pt =
286 surface_element_pt->make_bounding_element(1);
292 point_element_pt->wall_unit_normal_fct_pt() =
308 for(
unsigned e=0;e<n_element;e++)
311 ELEMENT *temp_pt =
dynamic_cast<ELEMENT*
>(
Bulk_mesh_pt->element_pt(e));
314 temp_pt->re_pt() = ℜ
316 temp_pt->re_st_pt() = ℜ
318 temp_pt->re_invfr_pt() = &ReInvFr;
320 temp_pt->g_pt() = &G;
327 bool elastic =
false;
328 if(
dynamic_cast<SolidNode*
>(
Bulk_mesh_pt->node_pt(0))) {elastic=
true;}
332 for(
unsigned j=0;j<n_node;j++)
342 static_cast<SolidNode*
>(
Bulk_mesh_pt->boundary_node_pt(0,j))
344 static_cast<SolidNode*
>(
Bulk_mesh_pt->boundary_node_pt(0,j))
352 for(
unsigned j=0;j<n_node;j++)
359 static_cast<SolidNode*
>(
Bulk_mesh_pt->boundary_node_pt(3,j))
367 for(
unsigned j=0;j<n_node;j++)
374 static_cast<SolidNode*
>(
Bulk_mesh_pt->boundary_node_pt(1,j))
381 std::cout << assign_eqn_numbers() <<
" in the main problem" << std::endl;
389 this->Point_mesh_pt->flush_node_storage();
393 this->Surface_mesh_pt->flush_node_storage();
396 this->Traction_mesh_pt->flush_node_storage();
401 delete this->time_stepper_pt();
410template<
class ELEMENT,
class INTERFACE_ELEMENT>
418 unsigned n_node = Bulk_mesh_pt->nnode();
419 for(
unsigned n=0;n<n_node;n++)
421 double y = Bulk_mesh_pt->node_pt(n)->x(1);
423 Bulk_mesh_pt->node_pt(n)->set_value(0,0.5*ReInvFr*sin(Alpha)*(2.0*y - y*y));
428 steady_newton_solve();
431 std::string filename = Output_prefix;;
432 filename.append(
"_output.dat");
433 ofstream file(filename.c_str());
434 Bulk_mesh_pt->output(file,5);
442template<
class ELEMENT,
class INTERFACE_ELEMENT>
444timestep(
const double &dt,
const unsigned &n_tsteps)
450 std::string filename = Output_prefix;
451 filename.append(
"_time_trace.dat");
452 ofstream trace(filename.c_str());
459 trace << time_pt()->time() <<
" "
460 << Bulk_mesh_pt->boundary_node_pt(2,0)->value(1)
463 boundary_node_pt(2, Bulk_mesh_pt->nboundary_node(2)-1)->x(1)
468 for(
unsigned t=1;t<=n_tsteps;t++)
473 cout <<
"--------------TIMESTEP " << t<<
" ------------------" << std::endl;
476 unsteady_newton_solve(dt);
482 std::ostringstream filename;
483 filename << Output_prefix <<
"_step" << Re <<
"_" << t <<
".dat";
484 file.open(filename.str().c_str());
485 Bulk_mesh_pt->output(file,5);
494 std::ostringstream filename;
495 filename << Output_prefix <<
"_interface_" << Re <<
"_" << t <<
".dat";
496 file.open(filename.str().c_str());
497 Surface_mesh_pt->output(file,5);
503 trace << time_pt()->time() <<
" "
504 << Bulk_mesh_pt->boundary_node_pt(2,0)->x(1) <<
" "
507 boundary_node_pt(2,Bulk_mesh_pt->nboundary_node(2)-1)->x(1) <<
" "
521template <
class ELEMENT>
523 public SimpleRectangularQuadMesh<ELEMENT>,
528 const double &lx,
const double &ly,
529 TimeStepper* time_stepper_pt) :
530 SimpleRectangularQuadMesh<ELEMENT>
531 (nx,ny,lx,ly,time_stepper_pt), SpineMesh()
534 unsigned n_p =
dynamic_cast<ELEMENT*
>(finite_element_pt(0))->nnode_1d();
536 Spine_pt.reserve((n_p-1)*nx + 1);
539 Spine* new_spine_pt=0;
542 for(
unsigned long j=0;j<nx;j++)
546 unsigned n_pmax = n_p-1;
548 if(j==nx-1) {n_pmax = n_p;}
551 for(
unsigned l2=0;l2<n_pmax;l2++)
554 new_spine_pt=
new Spine(1.0);
555 Spine_pt.push_back(new_spine_pt);
558 SpineNode* nod_pt=element_node_pt(j,l2);
560 nod_pt->spine_pt() = new_spine_pt;
562 nod_pt->fraction() = 0.0;
564 nod_pt->spine_mesh_pt() =
this;
568 for(
unsigned long i=0;i<ny;i++)
571 for(
unsigned l1=1;l1<n_p;l1++)
574 SpineNode* nod_pt=element_node_pt(i*nx+j,l1*n_p+l2);
576 nod_pt->spine_pt() = new_spine_pt;
578 nod_pt->fraction()=(double(i)+double(l1)/double(n_p-1))/
double(ny);
580 nod_pt->spine_mesh_pt() =
this;
593 double W = spine_node_pt->fraction();
595 double H = spine_node_pt->h();
597 spine_node_pt->x(1) = W*H;
606template<
class ELEMENT,
class TIMESTEPPER>
614 const double &length):
622 this->add_time_stepper_pt(
new TIMESTEPPER);
663template <
class ELEMENT>
665 public SimpleRectangularQuadMesh<ELEMENT>,
671 const double &
lx,
const double &
ly,
686template<
class ELEMENT,
class TIMESTEPPER>
716 temp_pt->constitutive_law_pt() =
764#define FLUID_ELEMENT QCrouzeixRaviartElement<2>
766#define FLUID_ELEMENT QTaylorHoodElement<2>
778 Wall_normal.resize(2);
779 Wall_normal[0] = -1.0;
780 Wall_normal[1] = 0.0;
794 problem.assign_initial_values_impulsive(
dt);
814 problem.assign_initial_values_impulsive(
dt);
Create an Elastic mesh for the problem.
ElasticInclinedPlaneMesh(const unsigned &nx, const unsigned &ny, const double &lx, const double &ly, TimeStepper *time_stepper_pt)
ElasticInclinedPlaneProblem(const unsigned &nx, const unsigned &ny, const double &length)
void actions_after_implicit_timestep()
Update Lagrangian positions after each timestep (updated-lagrangian approach)
Generic problem class that will form the base class for both spine and elastic mesh-updates of the pr...
void solve_steady()
Solve the steady problem.
Mesh * Bulk_mesh_pt
Bulk fluid mesh.
void make_traction_elements()
Function to add the traction boundary elements to boundaries 3(inlet) and 1(outlet) of the mesh.
InclinedPlaneProblem(const unsigned &nx, const unsigned &ny, const double &length)
Generic Constructor (empty)
std::string Output_prefix
Prefix for output files.
void timestep(const double &dt, const unsigned &n_tsteps)
Take n_tsteps timesteps of size dt.
void make_free_surface_elements()
Mesh * Traction_mesh_pt
Mesh for the traction elements that are added at inlet and outlet.
Mesh * Surface_mesh_pt
Mesh for the free surface elements.
~InclinedPlaneProblem()
Generic desructor to clean up the memory allocated in the problem.
Mesh * Point_mesh_pt
Mesh for the point elements at each end of the free surface.
void complete_build()
Complete the build of the problem setting all standard parameters and boundary conditions.
void actions_before_implicit_timestep()
Actions before the timestep (update the time-dependent boundary conditions)
Create a spine mesh for the problem.
virtual void spine_node_update(SpineNode *spine_node_pt)
General node update function implements pure virtual function defined in SpineMesh base class and per...
SpineInclinedPlaneMesh(const unsigned &nx, const unsigned &ny, const double &lx, const double &ly, TimeStepper *time_stepper_pt)
SpineInclinedPlaneProblem(const unsigned &nx, const unsigned &ny, const double &length)
void actions_before_newton_convergence_check()
Spine heights/lengths are unknowns in the problem so their values get corrected during each Newton st...
int main(int argc, char **argv)
double Inlet_Angle
The contact angle that is imposed at the inlet (pi)
ConstitutiveLaw * Constitutive_law_pt
Constitutive law used to determine the mesh deformation.
double Nu
Pseudo-solid Poisson ratio.
Vector< double > Wall_normal
Direction of the wall normal vector (at the inlet)
void wall_unit_normal_outlet_fct(const Vector< double > &x, Vector< double > &normal)
Function that specified the wall unit normal at the outlet.
double Ca
The Capillary number.
double Length
The length of the domain to fit the desired number of waves.
double K
Set the wavenumber.
void wall_unit_normal_inlet_fct(const Vector< double > &x, Vector< double > &normal)
Function that specifies the wall unit normal at the inlet.
double Alpha
Angle of incline of the slope (45 degrees)
double ReInvFr
The product of Reynolds number and inverse Froude number is set to two in this problem,...
void hydrostatic_pressure_outlet(const double &time, const Vector< double > &x, const Vector< double > &n, Vector< double > &traction)
Function that prescribes the hydrostatic pressure field at the outlet.
double Re
Reynolds number, based on the average velocity within the fluid film.
Vector< double > G(2, 0.0)
The Vector direction of gravity, set in main()
double N_wave
Set the number of waves desired in the domain.
void hydrostatic_pressure_inlet(const double &time, const Vector< double > &x, const Vector< double > &n, Vector< double > &traction)
Function that prescribes hydrostatic pressure field at the inlet.