37 #include "navier_stokes.h" 40 #include "fluid_interface.h" 43 #include "constitutive.h" 49 #include "meshes/rectangular_quadmesh.h" 53 using namespace oomph;
105 template <
class ELEMENT>
107 public virtual ElasticRefineableRectangularQuadMesh<ELEMENT>
123 const bool& periodic_in_x,
124 TimeStepper* time_stepper_pt=
125 &Mesh::Default_TimeStepper)
126 : RectangularQuadMesh<ELEMENT>(nx,ny1+ny2,lx,h1+h2,
127 periodic_in_x,time_stepper_pt),
128 ElasticRectangularQuadMesh<ELEMENT>(nx,ny1+ny2,lx,h1+h2,
129 periodic_in_x,time_stepper_pt),
130 ElasticRefineableRectangularQuadMesh<ELEMENT>(nx,ny1+ny2,lx,h1+h2,
139 this->set_nboundary(5);
142 for(
unsigned e=0;e<nx;e++)
145 FiniteElement* el_pt = this->finite_element_pt(nx*(ny1-1)+e);
148 const unsigned n_node = el_pt->nnode();
152 for(
unsigned n=0;n<3;n++)
154 Node* nod_pt = el_pt->node_pt(n_node-3+n);
155 this->convert_to_boundary_node(nod_pt);
156 this->add_boundary_node(4,nod_pt);
161 this->setup_boundary_element_info();
176 template <
class ELEMENT,
class TIMESTEPPER>
189 void set_initial_condition();
192 void set_boundary_conditions();
195 void doc_solution(DocInfo &doc_info);
198 void unsteady_run(
const double &t_max,
const double &dt);
212 Bulk_mesh_pt->set_lagrangian_nodal_coordinates();
216 void actions_before_adapt();
219 void actions_after_adapt();
222 void create_interface_elements();
225 void delete_interface_elements();
228 void deform_free_surface(
const double &epsilon,
const unsigned &n_periods);
232 const unsigned &pdof,
233 const double &pvalue)
236 dynamic_cast<ELEMENT*
>(mesh_pt()->element_pt(e))->
237 fix_pressure(pdof,pvalue);
262 template <
class ELEMENT,
class TIMESTEPPER>
267 add_time_stepper_pt(
new TIMESTEPPER);
270 const unsigned n_x = 3;
273 const unsigned n_y1 = 3;
276 const unsigned n_y2 = 3;
279 const double l_x = 1.0;
283 const double h1 = 1.0;
286 const double h2 = 1.0;
291 (n_x,n_y1,n_y2,l_x,h1,h2,
true,time_stepper_pt());
294 Bulk_mesh_pt->spatial_error_estimator_pt() =
new Z2ErrorEstimator;
297 Bulk_mesh_pt->max_refinement_level() = 4;
302 Surface_mesh_pt =
new Mesh;
306 create_interface_elements();
309 add_sub_mesh(Bulk_mesh_pt);
310 add_sub_mesh(Surface_mesh_pt);
323 const unsigned n_boundary = Bulk_mesh_pt->nboundary();
326 for(
unsigned b=0;b<n_boundary;b++)
329 const unsigned n_node = Bulk_mesh_pt->nboundary_node(b);
332 for(
unsigned n=0;n<n_node;n++)
339 if(b!=4) { Bulk_mesh_pt->boundary_node_pt(b,n)->pin(0); }
342 if(b==0 || b==2) { Bulk_mesh_pt->boundary_node_pt(b,n)->pin(1); }
348 if(b==0 || b==2) { Bulk_mesh_pt->boundary_node_pt(b,n)->pin_position(1); }
354 const unsigned n_node = Bulk_mesh_pt->nnode();
355 for(
unsigned n=0;n<n_node;n++) { Bulk_mesh_pt->node_pt(n)->pin_position(0); }
365 const unsigned n_lower = n_x*n_y1;
366 const unsigned n_upper = n_x*n_y2;
369 for(
unsigned e=0;e<n_lower;e++)
372 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
388 el_pt->constitutive_law_pt() = Constitutive_law_pt;
393 for(
unsigned e=n_lower;e<(n_lower+n_upper);e++)
396 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
418 el_pt->constitutive_law_pt() = Constitutive_law_pt;
423 fix_pressure(0,0,0.0);
426 set_boundary_conditions();
429 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
440 template <
class ELEMENT,
class TIMESTEPPER>
444 const unsigned n_node = mesh_pt()->nnode();
447 for(
unsigned n=0;n<n_node;n++)
450 for(
unsigned i=0;i<2;i++)
453 mesh_pt()->node_pt(n)->set_value(i,0.0);
459 assign_initial_values_impulsive();
470 template <
class ELEMENT,
class TIMESTEPPER>
474 const unsigned n_boundary = Bulk_mesh_pt->nboundary();
477 for(
unsigned b=0;b<n_boundary;b++)
480 const unsigned n_node = Bulk_mesh_pt->nboundary_node(b);
483 for(
unsigned n=0;n<n_node;n++)
487 if(b!=4) { Bulk_mesh_pt->boundary_node_pt(b,n)->set_value(0,0.0); }
493 Bulk_mesh_pt->boundary_node_pt(b,n)->set_value(1,0.0);
505 template<
class ELEMENT,
class TIMESTEPPER>
509 delete_interface_elements();
512 rebuild_global_mesh();
521 template<
class ELEMENT,
class TIMESTEPPER>
525 this->create_interface_elements();
528 rebuild_global_mesh();
531 const unsigned n_node = Bulk_mesh_pt->nnode();
532 for(
unsigned n=0;n<n_node;n++) { Bulk_mesh_pt->node_pt(n)->pin_position(0); }
535 RefineableNavierStokesEquations<2>::
536 unpin_all_pressure_dofs(Bulk_mesh_pt->element_pt());
539 RefineableNavierStokesEquations<2>::
540 pin_redundant_nodal_pressures(Bulk_mesh_pt->element_pt());
543 fix_pressure(0,0,0.0);
546 PVDEquationsBase<2>::pin_redundant_nodal_solid_pressures(
547 Bulk_mesh_pt->element_pt());
550 set_boundary_conditions();
561 template <
class ELEMENT,
class TIMESTEPPER>
565 const unsigned n_element = this->Bulk_mesh_pt->nboundary_element(4);
568 for(
unsigned e=0;e<n_element;e++)
571 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(
572 this->Bulk_mesh_pt->boundary_element_pt(4,e));
577 if(bulk_elem_pt->viscosity_ratio_pt()
581 const int face_index = this->Bulk_mesh_pt->face_index_at_boundary(4,e);
584 FiniteElement* interface_element_element_pt =
585 new ElasticLineFluidInterfaceElement<ELEMENT>(bulk_elem_pt,face_index);
588 this->Surface_mesh_pt->add_element_pt(interface_element_element_pt);
597 const unsigned n_interface_element = this->Surface_mesh_pt->nelement();
600 for(
unsigned e=0;e<n_interface_element;e++)
603 ElasticLineFluidInterfaceElement<ELEMENT>* el_pt =
604 dynamic_cast<ElasticLineFluidInterfaceElement<ELEMENT>*
> 605 (Surface_mesh_pt->element_pt(e));
622 template <
class ELEMENT,
class TIMESTEPPER>
626 const unsigned n_interface_element = Surface_mesh_pt->nelement();
629 for(
unsigned e=0;e<n_interface_element;e++)
631 delete Surface_mesh_pt->element_pt(e);
635 Surface_mesh_pt->flush_element_and_node_storage();
644 template <
class ELEMENT,
class TIMESTEPPER>
649 const unsigned n_node = Bulk_mesh_pt->nnode();
652 for(
unsigned n=0;n<n_node;n++)
655 const double current_x_pos = Bulk_mesh_pt->node_pt(n)->x(0);
656 const double current_y_pos = Bulk_mesh_pt->node_pt(n)->x(1);
659 const double new_y_pos = current_y_pos
660 + (1.0-fabs(1.0-current_y_pos))*epsilon
661 *(cos(2.0*n_periods*MathematicalConstants::Pi*current_x_pos/Lx));
664 Bulk_mesh_pt->node_pt(n)->x(1) = new_y_pos;
673 template <
class ELEMENT,
class TIMESTEPPER>
678 cout <<
"Time is now " << time_pt()->time() << std::endl;
681 ElasticLineFluidInterfaceElement<ELEMENT>* el_pt =
682 dynamic_cast<ElasticLineFluidInterfaceElement<ELEMENT>*
> 683 (Surface_mesh_pt->element_pt(0));
687 Trace_file << time_pt()->time() <<
" " 688 << el_pt->node_pt(0)->x(1) << std::endl;
694 const unsigned npts = 5;
697 sprintf(filename,
"%s/soln%i.dat",
698 doc_info.directory().c_str(),doc_info.number());
699 some_file.open(filename);
702 Bulk_mesh_pt->output(some_file,npts);
708 sprintf(filename,
"%s/interface_soln%i.dat",
709 doc_info.directory().c_str(),doc_info.number());
710 some_file.open(filename);
713 Surface_mesh_pt->output(some_file,npts);
725 template <
class ELEMENT,
class TIMESTEPPER>
731 const double epsilon = 0.1;
734 const unsigned n_periods = 1;
737 deform_free_surface(epsilon,n_periods);
743 doc_info.set_directory(
"RESLT");
750 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
751 Trace_file.open(filename);
754 Trace_file <<
"time, interface height" << std::endl;
760 set_initial_condition();
763 unsigned max_adapt = 2;
766 for(
unsigned i=0;i<2;i++) { refine_uniformly(); }
769 doc_solution(doc_info);
775 const unsigned n_timestep = unsigned(t_max/dt);
778 bool first_timestep =
true;
781 for(
unsigned t=1;t<=n_timestep;t++)
784 cout <<
"\nTimestep " << t <<
" of " << n_timestep << std::endl;
787 unsteady_newton_solve(dt,max_adapt,first_timestep);
790 first_timestep =
false;
796 doc_solution(doc_info);
814 int main(
int argc,
char* argv[])
817 CommandLineArgs::setup(argc,argv);
825 CommandLineArgs::specify_command_line_flag(
"--validation");
828 CommandLineArgs::parse_and_assign();
831 CommandLineArgs::doc_specified_flags();
838 std::ostringstream error_stream;
839 error_stream <<
"Definition of Global_Physical_Variables::ReSt is " 840 <<
"inconsistant with those\n" 841 <<
"of Global_Physical_Variables::Re and " 842 <<
"Global_Physical_Variables::St." << std::endl;
843 throw OomphLibError(error_stream.str(),
844 OOMPH_CURRENT_FUNCTION,OOMPH_EXCEPTION_LOCATION);
851 const double dt = 0.0025;
854 if(CommandLineArgs::command_line_flag_has_been_set(
"--validation"))
866 RefineableQCrouzeixRaviartElement<2>,RefineableQPVDElement<2,3> >, BDF<2> >
double Lx
Width of domain.
void actions_before_adapt()
Strip off the interface elements before adapting the bulk mesh.
InterfaceProblem()
Constructor.
Vector< double > G(2)
Direction of gravity.
Mesh * Surface_mesh_pt
Pointer to the "surface" mesh.
double St
Strouhal number.
ElasticRefineableTwoLayerMesh(const unsigned &nx, const unsigned &ny1, const unsigned &ny2, const double &lx, const double &h1, const double &h2, const bool &periodic_in_x, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor: Pass number of elements in x-direction, number of elements in y-direction in bottom and ...
void delete_interface_elements()
Delete the 1d interface elements.
ofstream Trace_file
Trace file.
void actions_before_newton_solve()
No actions required before solve step.
double ReSt
Womersley number (Reynolds x Strouhal)
void actions_after_adapt()
Rebuild the mesh of interface elements after adapting the bulk mesh.
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.
~InterfaceProblem()
Destructor (empty)
double Density_Ratio
Ratio of density in upper fluid to density in lower fluid. Reynolds number etc. is based on density i...
double Re
Reynolds number.
void actions_after_newton_solve()
No actions required after solve step.
void set_boundary_conditions()
Set boundary conditions.
void set_initial_condition()
Set initial conditions.
void unsteady_run(const double &t_max, const double &dt)
Do unsteady run up to maximum time t_max with given timestep dt.
double Viscosity_Ratio
Ratio of viscosity in upper fluid to viscosity in lower fluid. Reynolds number etc. is based on viscosity in lower fluid.
void create_interface_elements()
Create the 1d interface elements.
Namespace for physical parameters.
void deform_free_surface(const double &epsilon, const unsigned &n_periods)
Deform the mesh/free surface to a prescribed function.
double ReInvFr
Product of Reynolds number and inverse of Froude number.
ElasticRefineableTwoLayerMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the (specific) "bulk" mesh.
void actions_before_implicit_timestep()
Actions before the timestep: For maximum stability, reset the current nodal positions to be the "stre...
int main(int argc, char *argv[])
Driver code for two-dimensional two fluid interface problem.
void doc_solution(DocInfo &doc_info)
Document the solution.
ConstitutiveLaw * Constitutive_law_pt
double Nu
Pseudo-solid Poisson ratio.
double Ca
Capillary number.