45 #include "navier_stokes.h" 47 #include "fluid_interface.h" 48 #include "meshes/simple_rectangular_quadmesh.h" 52 using namespace oomph;
70 Vector<double>
G(2,0.0);
89 Vector<double> &normal)
96 Vector<double> &normal)
101 unsigned n_dim = normal.size();
102 for(
unsigned i=0;i<n_dim;++i) {normal[i] *= -1.0;}
111 const Vector<double> &n,
112 Vector<double> &traction)
114 traction[0] = ReInvFr*
G[1]*(1.0 - x[1]);
120 const Vector<double> &n,
121 Vector<double> &traction)
123 traction[0] = -ReInvFr*
G[1]*(1.0 - x[1]);
141 template<
class ELEMENT,
class INTERFACE_ELEMENT>
166 const double &length) :
167 Output_prefix(
"Unset") { }
173 void timestep(
const double &dt,
const unsigned &n_tsteps);
180 double time = this->time_pt()->time();
183 double epsilon = 0.01;
185 unsigned n_node = this->Bulk_mesh_pt->nboundary_node(0);
186 for(
unsigned n=0;n<n_node;n++)
188 Node* nod_pt = this->Bulk_mesh_pt->boundary_node_pt(0,n);
190 double value = sin(arg)*epsilon*time*exp(-time);
191 nod_pt->set_value(1,value);
200 Traction_mesh_pt =
new Mesh;
205 unsigned n_boundary_element = Bulk_mesh_pt->nboundary_element(b);
207 for(
unsigned e=0;e<n_boundary_element;e++)
209 NavierStokesTractionElement<ELEMENT> *surface_element_pt =
210 new NavierStokesTractionElement<ELEMENT>
211 (Bulk_mesh_pt->boundary_element_pt(b,e),
212 Bulk_mesh_pt->face_index_at_boundary(b,e));
214 Traction_mesh_pt->add_element_pt(surface_element_pt);
216 surface_element_pt->traction_fct_pt() =
225 unsigned n_boundary_element = Bulk_mesh_pt->nboundary_element(b);
227 for(
unsigned e=0;e<n_boundary_element;e++)
229 NavierStokesTractionElement<ELEMENT> *surface_element_pt =
230 new NavierStokesTractionElement<ELEMENT>
231 (Bulk_mesh_pt->boundary_element_pt(b,e),
232 Bulk_mesh_pt->face_index_at_boundary(b,e));
234 Traction_mesh_pt->add_element_pt(surface_element_pt);
236 surface_element_pt->traction_fct_pt() =
246 Surface_mesh_pt =
new Mesh;
247 Point_mesh_pt =
new Mesh;
251 unsigned n_boundary_element = Bulk_mesh_pt->nboundary_element(b);
253 for(
unsigned e=0;e<n_boundary_element;e++)
255 INTERFACE_ELEMENT *surface_element_pt =
256 new INTERFACE_ELEMENT
257 (Bulk_mesh_pt->boundary_element_pt(b,e),
258 Bulk_mesh_pt->face_index_at_boundary(b,e));
260 Surface_mesh_pt->add_element_pt(surface_element_pt);
262 surface_element_pt->ca_pt() =
270 FluidInterfaceBoundingElement* point_element_pt =
271 surface_element_pt->make_bounding_element(-1);
273 Point_mesh_pt->add_element_pt(point_element_pt);
277 point_element_pt->wall_unit_normal_fct_pt() =
280 point_element_pt->set_contact_angle(
287 if(e==n_boundary_element-1)
289 FluidInterfaceBoundingElement* point_element_pt =
290 surface_element_pt->make_bounding_element(1);
292 Point_mesh_pt->add_element_pt(point_element_pt);
296 point_element_pt->wall_unit_normal_fct_pt() =
310 unsigned n_element = Bulk_mesh_pt->nelement();
312 for(
unsigned e=0;e<n_element;e++)
315 ELEMENT *temp_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
318 temp_pt->re_pt() = &
Re;
320 temp_pt->re_st_pt() = &
Re;
322 temp_pt->re_invfr_pt() = &
ReInvFr;
324 temp_pt->g_pt() = &
G;
331 bool elastic =
false;
332 if(dynamic_cast<SolidNode*>(Bulk_mesh_pt->node_pt(0))) {elastic=
true;}
335 unsigned n_node = Bulk_mesh_pt->nboundary_node(0);
336 for(
unsigned j=0;j<n_node;j++)
339 Bulk_mesh_pt->boundary_node_pt(0,j)->pin(0);
340 Bulk_mesh_pt->boundary_node_pt(0,j)->pin(1);
346 static_cast<SolidNode*
>(Bulk_mesh_pt->boundary_node_pt(0,j))
348 static_cast<SolidNode*
>(Bulk_mesh_pt->boundary_node_pt(0,j))
355 n_node = Bulk_mesh_pt->nboundary_node(3);
356 for(
unsigned j=0;j<n_node;j++)
358 Bulk_mesh_pt->boundary_node_pt(3,j)->pin(1);
363 static_cast<SolidNode*
>(Bulk_mesh_pt->boundary_node_pt(3,j))
370 n_node = Bulk_mesh_pt->nboundary_node(1);
371 for(
unsigned j=0;j<n_node;j++)
373 Bulk_mesh_pt->boundary_node_pt(1,j)->pin(1);
378 static_cast<SolidNode*
>(Bulk_mesh_pt->boundary_node_pt(1,j))
385 std::cout << assign_eqn_numbers() <<
" in the main problem" << std::endl;
393 this->Point_mesh_pt->flush_node_storage();
395 delete this->Point_mesh_pt;
397 this->Surface_mesh_pt->flush_node_storage();
398 delete this->Surface_mesh_pt;
400 this->Traction_mesh_pt->flush_node_storage();
401 delete this->Traction_mesh_pt;
403 delete this->Bulk_mesh_pt;
405 delete this->time_stepper_pt();
414 template<
class ELEMENT,
class INTERFACE_ELEMENT>
422 unsigned n_node = Bulk_mesh_pt->nnode();
423 for(
unsigned n=0;n<n_node;n++)
425 double y = Bulk_mesh_pt->node_pt(n)->x(1);
427 Bulk_mesh_pt->node_pt(n)->set_value(0,0.5*
ReInvFr*sin(
Alpha)*(2.0*y - y*y));
432 steady_newton_solve();
435 std::string filename = Output_prefix;;
436 filename.append(
"_output.dat");
437 ofstream file(filename.c_str());
438 Bulk_mesh_pt->output(file,5);
446 template<
class ELEMENT,
class INTERFACE_ELEMENT>
448 timestep(
const double &dt,
const unsigned &n_tsteps)
454 std::string filename = Output_prefix;
455 filename.append(
"_time_trace.dat");
456 ofstream trace(filename.c_str());
463 trace << time_pt()->time() <<
" " 464 << Bulk_mesh_pt->boundary_node_pt(2,0)->value(1)
467 boundary_node_pt(2, Bulk_mesh_pt->nboundary_node(2)-1)->x(1)
472 for(
unsigned t=1;t<=n_tsteps;t++)
477 cout <<
"--------------TIMESTEP " << t<<
" ------------------" << std::endl;
480 unsteady_newton_solve(dt);
486 std::ostringstream filename;
487 filename << Output_prefix <<
"_step" <<
Re <<
"_" << t <<
".dat";
488 file.open(filename.str().c_str());
489 Bulk_mesh_pt->output(file,5);
498 std::ostringstream filename;
499 filename << Output_prefix <<
"_interface_" <<
Re <<
"_" << t <<
".dat";
500 file.open(filename.str().c_str());
501 Surface_mesh_pt->output(file,5);
507 trace << time_pt()->time() <<
" " 508 << Bulk_mesh_pt->boundary_node_pt(2,0)->x(1) <<
" " 511 boundary_node_pt(2,Bulk_mesh_pt->nboundary_node(2)-1)->x(1) <<
" " 525 template <
class ELEMENT>
527 public SimpleRectangularQuadMesh<ELEMENT>,
532 const double &lx,
const double &ly,
533 TimeStepper* time_stepper_pt) :
534 SimpleRectangularQuadMesh<ELEMENT>
535 (nx,ny,lx,ly,time_stepper_pt), SpineMesh()
538 unsigned n_p =
dynamic_cast<ELEMENT*
>(finite_element_pt(0))->nnode_1d();
540 Spine_pt.reserve((n_p-1)*nx + 1);
543 Spine* new_spine_pt=0;
546 for(
unsigned long j=0;j<nx;j++)
550 unsigned n_pmax = n_p-1;
552 if(j==nx-1) {n_pmax = n_p;}
555 for(
unsigned l2=0;l2<n_pmax;l2++)
558 new_spine_pt=
new Spine(1.0);
559 Spine_pt.push_back(new_spine_pt);
562 SpineNode* nod_pt=element_node_pt(j,l2);
564 nod_pt->spine_pt() = new_spine_pt;
566 nod_pt->fraction() = 0.0;
568 nod_pt->spine_mesh_pt() =
this;
572 for(
unsigned long i=0;i<ny;i++)
575 for(
unsigned l1=1;l1<n_p;l1++)
578 SpineNode* nod_pt=element_node_pt(i*nx+j,l1*n_p+l2);
580 nod_pt->spine_pt() = new_spine_pt;
582 nod_pt->fraction()=(double(i)+double(l1)/double(n_p-1))/
double(ny);
584 nod_pt->spine_mesh_pt() =
this;
597 double W = spine_node_pt->fraction();
599 double H = spine_node_pt->h();
601 spine_node_pt->x(1) = W*H;
610 template<
class ELEMENT,
class TIMESTEPPER>
618 const double &length):
623 this->Output_prefix =
"spine";
626 this->add_time_stepper_pt(
new TIMESTEPPER);
630 nx,ny,length,1.0,this->time_stepper_pt());
633 this->make_traction_elements();
635 this->make_free_surface_elements();
638 this->add_sub_mesh(this->Bulk_mesh_pt);
639 this->add_sub_mesh(this->Traction_mesh_pt);
640 this->add_sub_mesh(this->Surface_mesh_pt);
641 this->add_sub_mesh(this->Point_mesh_pt);
643 this->build_global_mesh();
646 this->complete_build();
654 {this->Bulk_mesh_pt->node_update();}
667 template <
class ELEMENT>
669 public SimpleRectangularQuadMesh<ELEMENT>,
675 const double &lx,
const double &ly,
676 TimeStepper* time_stepper_pt) :
677 SimpleRectangularQuadMesh<ELEMENT>(nx,ny,lx,ly,time_stepper_pt), SolidMesh()
680 set_lagrangian_nodal_coordinates();
690 template<
class ELEMENT,
class TIMESTEPPER>
697 const double &length) :
702 this->Output_prefix =
"elastic";
705 this->add_time_stepper_pt(
new TIMESTEPPER);
709 nx,ny,length,1.0,this->time_stepper_pt());
712 unsigned n_element = this->Bulk_mesh_pt->nelement();
714 for(
unsigned e=0;e<n_element;e++)
717 ELEMENT *temp_pt =
dynamic_cast<ELEMENT*
>(
718 this->Bulk_mesh_pt->element_pt(e));
720 temp_pt->constitutive_law_pt() =
725 this->make_traction_elements();
727 this->make_free_surface_elements();
730 this->add_sub_mesh(this->Bulk_mesh_pt);
731 this->add_sub_mesh(this->Traction_mesh_pt);
732 this->add_sub_mesh(this->Surface_mesh_pt);
733 this->add_sub_mesh(this->Point_mesh_pt);
735 this->build_global_mesh();
738 this->complete_build();
746 unsigned n_node = this->Bulk_mesh_pt->nnode();
747 for(
unsigned n=0;n<n_node;n++)
751 static_cast<SolidNode*
>(this->Bulk_mesh_pt->node_pt(n));
752 for(
unsigned j=0;j<2;j++) {temp_pt->xi(j) = temp_pt->x(j);}
760 int main(
int argc,
char **argv)
768 #define FLUID_ELEMENT QCrouzeixRaviartElement<2> 770 #define FLUID_ELEMENT QTaylorHoodElement<2> 798 problem.assign_initial_values_impulsive(dt);
809 PseudoSolidNodeUpdateElement<FLUID_ELEMENT,QPVDElement<2,3> >, BDF<2> >
813 problem.solve_steady();
818 problem.assign_initial_values_impulsive(dt);
821 problem.timestep(dt,2);
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.
double K
Set the wavenumber.
void make_free_surface_elements()
void timestep(const double &dt, const unsigned &n_tsteps)
Take n_tsteps timesteps of size dt.
double N_wave
Set the number of waves desired in the domain.
Mesh * Point_mesh_pt
Mesh for the point elements at each end of the free surface.
void actions_before_implicit_timestep()
Actions before the timestep (update the time-dependent boundary conditions)
Mesh * Bulk_mesh_pt
Bulk fluid mesh.
Mesh * Surface_mesh_pt
Mesh for the free surface elements.
Vector< double > Wall_normal
Direction of the wall normal vector (at the inlet)
Generic problem class that will form the base class for both spine and elastic mesh-updates of the pr...
std::string Output_prefix
Prefix for output files.
ConstitutiveLaw * Constitutive_law_pt
Constitutive law used to determine the mesh deformation.
virtual void spine_node_update(SpineNode *spine_node_pt)
General node update function implements pure virtual function defined in SpineMesh base class and per...
void actions_before_newton_convergence_check()
SpineInclinedPlaneProblem(const unsigned &nx, const unsigned &ny, const double &length)
void actions_after_implicit_timestep()
Update Lagrangian positions after each timestep (updated-lagrangian approach)
int main(int argc, char **argv)
ElasticInclinedPlaneProblem(const unsigned &nx, const unsigned &ny, const double &length)
void wall_unit_normal_outlet_fct(const Vector< double > &x, Vector< double > &normal)
Function that specified the wall unit normal 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()
void wall_unit_normal_inlet_fct(const Vector< double > &x, Vector< double > &normal)
Function that specifies the wall unit normal at the inlet.
~InclinedPlaneProblem()
Generic desructor to clean up the memory allocated in the problem.
void complete_build()
Complete the build of the problem setting all standard parameters and boundary conditions.
Mesh * Traction_mesh_pt
Mesh for the traction elements that are added at inlet and outlet.
double Length
The length of the domain to fit the desired number of waves.
void make_traction_elements()
Function to add the traction boundary elements to boundaries 3(inlet) and 1(outlet) of the mesh...
ElasticInclinedPlaneMesh(const unsigned &nx, const unsigned &ny, const double &lx, const double &ly, TimeStepper *time_stepper_pt)
double Inlet_Angle
The contact angle that is imposed at the inlet (pi)
Create a spine mesh for the 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.
SpineInclinedPlaneMesh(const unsigned &nx, const unsigned &ny, const double &lx, const double &ly, TimeStepper *time_stepper_pt)
InclinedPlaneProblem(const unsigned &nx, const unsigned &ny, const double &length)
Generic Constructor (empty)
double Nu
Pseudo-solid Poisson ratio.
void solve_steady()
Solve the steady problem.
Create an Elastic mesh for the problem.
double Ca
The Capillary number.
double Alpha
Angle of incline of the slope (45 degrees)