37 #include "navier_stokes.h" 40 #include "multi_physics.h" 43 #include "meshes/cylinder_with_flag_mesh.h" 44 #include "meshes/rectangular_quadmesh.h" 49 using namespace oomph;
114 const Vector<double> &xi,
136 return Min_flux+(Max_flux-
Min_flux)*
137 0.5*(1.0-cos(MathematicalConstants::Pi*t/Ramp_period));
181 Ignore_fluid_loading=
false;
186 Lambda_sq=Re*Q*Density_ratio*St*
St;
188 else if (case_id==
"FSI2")
215 Ignore_fluid_loading=
false;
220 Lambda_sq=Re*Q*Density_ratio*St*
St;
222 else if (case_id==
"FSI3")
249 Ignore_fluid_loading=
false;
254 Lambda_sq=Re*Q*Density_ratio*St*
St;
256 else if (case_id==
"CSM1")
284 Ignore_fluid_loading=
true;
291 else if (case_id==
"CSM3")
319 Ignore_fluid_loading=
true;
329 std::cout <<
"Wrong case_id: " << case_id << std::endl;
338 Constitutive_law_pt =
new GeneralisedHookean(&Nu,&E);
341 oomph_info << std::endl;
342 oomph_info <<
"-------------------------------------------" 344 oomph_info <<
"Case: " << case_id << std::endl;
345 oomph_info <<
"Re = " << Re << std::endl;
346 oomph_info <<
"St = " << St << std::endl;
347 oomph_info <<
"ReSt = " << ReSt << std::endl;
348 oomph_info <<
"Q = " << Q << std::endl;
349 oomph_info <<
"Dt = " << Dt << std::endl;
350 oomph_info <<
"Ramp_period = " << Ramp_period << std::endl;
351 oomph_info <<
"Max_flux = " << Max_flux << std::endl;
352 oomph_info <<
"Density_ratio = " << Density_ratio << std::endl;
353 oomph_info <<
"Lambda_sq = " << Lambda_sq << std::endl;
354 oomph_info <<
"Gravity = " << Gravity << std::endl;
355 oomph_info <<
"Ignore fluid = " << Ignore_fluid_loading<< std::endl;
356 oomph_info <<
"-------------------------------------------" 357 << std::endl << std::endl;
373 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT >
380 TurekProblem(
const double &length,
const double &height);
384 {
return Fluid_mesh_pt;}
388 {
return Solid_mesh_pt;}
392 {
return Traction_mesh_pt[i];}
395 void actions_after_adapt();
398 void doc_solution(DocInfo& doc_info, ofstream& trace_file);
409 void actions_before_newton_convergence_check();
412 void actions_before_implicit_timestep();
417 void create_fsi_traction_elements();
449 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT >
452 const double &height) : Domain_height(height),
453 Domain_length(length)
458 Max_newton_iterations=20;
474 Newmark<2>* flag_time_stepper_pt=
new Newmark<2>;
475 add_time_stepper_pt(flag_time_stepper_pt);
479 Vector<double> origin(2);
488 double l_x=6.0-origin[0];
491 solid_mesh_pt() =
new ElasticRefineableRectangularQuadMesh<SOLID_ELEMENT>(
492 n_x,n_y,l_x,l_y,origin,flag_time_stepper_pt);
495 Z2ErrorEstimator* solid_error_estimator_pt=
new Z2ErrorEstimator;
496 solid_mesh_pt()->spatial_error_estimator_pt()=solid_error_estimator_pt;
500 FiniteElement* el_pt=
solid_mesh_pt()->finite_element_pt(n_x*n_y/2-1);
503 unsigned nnod=el_pt->nnode();
508 std::cout <<
"Coordinates of solid control point " 539 for (
unsigned bound=0;bound<3;bound++)
542 for(
unsigned e=0;e<n_face_element;e++)
545 FSISolidTractionElement<SOLID_ELEMENT,2>* elem_pt=
546 dynamic_cast<FSISolidTractionElement<SOLID_ELEMENT,2>*
> 550 elem_pt->set_boundary_number_in_bulk_mesh(bound);
567 MeshAsGeomObject* tip_flag_pt=
571 MeshAsGeomObject* top_flag_pt=
582 Global_Parameters::Radius);
585 BDF<2>* fluid_time_stepper_pt=
new BDF<2>;
586 add_time_stepper_pt(fluid_time_stepper_pt);
590 new RefineableAlgebraicCylinderWithFlagMesh<FLUID_ELEMENT>
600 fluid_time_stepper_pt);
609 Z2ErrorEstimator* fluid_error_estimator_pt=
new Z2ErrorEstimator;
610 fluid_mesh_pt()->spatial_error_estimator_pt()=fluid_error_estimator_pt;
623 for (
unsigned i=0;i<3;i++)
640 unsigned n_side = mesh_pt()->nboundary_node(3);
643 for(
unsigned i=0;i<n_side;i++)
650 PVDEquationsBase<2>::pin_redundant_nodal_solid_pressures(
658 for(
unsigned ibound=0;ibound<num_bound;ibound++)
661 for (
unsigned inod=0;inod<num_nod;inod++)
677 RefineableNavierStokesEquations<2>::
678 pin_redundant_nodal_pressures(
fluid_mesh_pt()->element_pt());
690 for (
unsigned inod=0;inod<num_nod;inod++)
692 double ycoord =
Fluid_mesh_pt->boundary_node_pt(ibound,inod)->x(1);
694 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(0,uy);
695 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(1,0.0);
704 for(
unsigned i=0;i<n_element;i++)
707 SOLID_ELEMENT *el_pt =
dynamic_cast<SOLID_ELEMENT*
>(
711 el_pt->constitutive_law_pt() =
728 for (
unsigned e=0;e<nelem;e++)
731 FLUID_ELEMENT* el_pt =
dynamic_cast<FLUID_ELEMENT*
> 758 for(
unsigned ibound=5;ibound<8;ibound++ )
761 for (
unsigned inod=0;inod<num_nod;inod++)
764 set_auxiliary_node_update_fct_pt(
765 FSI_functions::apply_no_slip_on_moving_wall);
773 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
776 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
779 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
788 GMRES<CRDoubleMatrix>* iterative_linear_solver_pt =
789 new GMRES<CRDoubleMatrix>;
792 iterative_linear_solver_pt->max_iter() = 100;
795 iterative_linear_solver_pt->tolerance() = 1.0e-10;
798 linear_solver_pt()=iterative_linear_solver_pt;
801 FSIPreconditioner* prec_pt=
new FSIPreconditioner(
this);
810 prec_pt->use_block_triangular_version_with_fluid_on_solid();
813 iterative_linear_solver_pt->preconditioner_pt()= prec_pt;
822 #ifdef OOMPH_HAS_HYPRE 824 #ifndef OOMPH_HAS_MPI 827 Preconditioner* P_matrix_preconditioner_pt =
new HyprePreconditioner;
829 HyprePreconditioner* P_hypre_solver_pt =
830 static_cast<HyprePreconditioner*
>(P_matrix_preconditioner_pt);
834 Hypre_default_settings::
835 set_defaults_for_2D_poisson_problem(P_hypre_solver_pt);
838 prec_pt->navier_stokes_preconditioner_pt()->
839 set_p_preconditioner(P_matrix_preconditioner_pt);
842 P_hypre_solver_pt->disable_doc_time();
848 cout << assign_eqn_numbers() << std::endl;
859 template <
class FLUID_ELEMENT,
class SOLID_ELEMENT>
871 template <
class FLUID_ELEMENT,
class SOLID_ELEMENT>
876 double t=time_pt()->time();
884 for (
unsigned inod=0;inod<num_nod;inod++)
886 double ycoord =
Fluid_mesh_pt->boundary_node_pt(ibound,inod)->x(1);
888 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(0,uy);
889 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(1,0.0);
898 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT >
902 RefineableNavierStokesEquations<2>::
906 RefineableNavierStokesEquations<2>::
907 pin_redundant_nodal_pressures(
fluid_mesh_pt()->element_pt());
910 PVDEquationsBase<2>::
911 unpin_all_solid_pressure_dofs(
solid_mesh_pt()->element_pt());
914 PVDEquationsBase<2>::pin_redundant_nodal_solid_pressures(
925 for(
unsigned ibound=5;ibound<8;ibound++ )
928 for (
unsigned inod=0;inod<num_nod;inod++)
931 set_auxiliary_node_update_fct_pt(
932 FSI_functions::apply_no_slip_on_moving_wall);
938 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
941 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
944 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
956 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT >
961 std::set<SolidNode*> all_nodes;
964 for (
unsigned b=0;b<3;b++)
970 for(
unsigned e=0;e<n_element;e++)
973 SOLID_ELEMENT* bulk_elem_pt =
dynamic_cast<SOLID_ELEMENT*
>(
977 int face_index =
solid_mesh_pt()->face_index_at_boundary(b,e);
981 new FSISolidTractionElement<SOLID_ELEMENT,2>(bulk_elem_pt,face_index));
987 for (
unsigned j=0;j<nnod;j++)
997 for (std::set<SolidNode*>::iterator it=all_nodes.begin();
998 it!=all_nodes.end();it++)
1011 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT >
1013 DocInfo& doc_info, ofstream& trace_file)
1026 unsigned n_plot = 5;
1029 sprintf(filename,
"%s/solid_soln%i.dat",doc_info.directory().c_str(),
1031 some_file.open(filename);
1036 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
1038 some_file.open(filename);
1044 sprintf(filename,
"%s/traction%i.dat",doc_info.directory().c_str(),
1046 some_file.open(filename);
1048 for(
unsigned i=0;i<3;i++)
1052 for(
unsigned e=0;e<n_element;e++)
1054 FSISolidTractionElement<SOLID_ELEMENT,2>* el_pt =
1055 dynamic_cast<FSISolidTractionElement<SOLID_ELEMENT,2>*
> (
1058 el_pt->output(some_file,5);
1066 trace_file << time_pt()->time() <<
" " 1073 cout <<
"Doced solution for step " 1074 << doc_info.number()
1075 << std::endl << std::endl << std::endl;
1087 CommandLineArgs::setup(argc,argv);
1090 string case_id=
"FSI1";
1091 if (CommandLineArgs::Argc==1)
1093 oomph_info <<
"No command line arguments; running self-test FSI1" 1096 else if (CommandLineArgs::Argc==2)
1098 case_id=CommandLineArgs::Argv[1];
1102 oomph_info <<
"Wrong number of command line arguments" << std::endl;
1103 oomph_info <<
"Enter none (for default) or one (namely the case id" 1105 oomph_info <<
"which should be one of: FSI1, FSI2, FSI3, CSM1" 1108 std::cout <<
"Running case " << case_id << std::endl;
1116 ofstream trace_file;
1117 doc_info.set_directory(
"RESLT");
1118 trace_file.open(
"RESLT/trace.dat");
1126 RefineableQPVDElement<2,3> > problem(length, height);
1129 unsigned nstep=4000;
1132 std::cout <<
"Reducing number of steps for FSI1 " << std::endl;
1136 if (CommandLineArgs::Argc==1)
1138 std::cout <<
"Reducing number of steps for validation " << std::endl;
1146 problem.initialise_dt(dt);
1149 problem.assign_initial_values_impulsive(dt);
1153 doc_info.number()++;
1160 unsigned max_adapt=1;
1162 for(
unsigned i=0;i<nstep;i++)
1165 problem.unsteady_newton_solve(dt,max_adapt,first);
1171 doc_info.number()++;
double Centre_x
x position of centre of cylinder
Node * Solid_control_node_pt
Pointer to solid control node.
double Q
FSI parameter (default assignment for FSI1 test case)
SolidMesh *& traction_mesh_pt(const unsigned &i)
Access function for the i-th mesh of FSI traction elements.
ElasticRefineableRectangularQuadMesh< SOLID_ELEMENT > *& solid_mesh_pt()
Access function for the solid mesh.
void actions_before_implicit_timestep()
Update the time-dependent influx.
double Min_flux
Min. flux.
double Centre_y
y position of centre of cylinder
void actions_before_newton_solve()
Update function (empty)
double Ramp_period
Period for ramping up in flux.
Node * Fluid_control_node_pt
Pointer to fluid control node.
Vector< SolidMesh * > Traction_mesh_pt
Vector of pointers to mesh of FSI traction elements.
void actions_after_newton_solve()
Update function (empty)
double Density_ratio
Density ratio (solid to fluid; default assignment for FSI1 test case)
int main(int argc, char *argv[])
Driver.
double flux(const double &t)
Flux increases between Min_flux and Max_flux over period Ramp_period.
string Case_ID
Default case ID.
double Domain_height
Overall height of domain.
double St
Strouhal number (default assignment for FSI1 test case)
double Gravity
Non-dim gravity (default assignment for FSI1 test case)
void set_parameters(const string &case_id)
Set parameters for the various test cases.
ElasticRefineableRectangularQuadMesh< SOLID_ELEMENT > * Solid_mesh_pt
Pointer to solid mesh.
double Lambda_sq
Timescale ratio for solid (dependent parameter assigned in set_parameters())
RefineableAlgebraicCylinderWithFlagMesh< FLUID_ELEMENT > * Fluid_mesh_pt
Pointer to fluid mesh.
void create_fsi_traction_elements()
Create FSI traction elements.
void doc_solution(DocInfo &doc_info, ofstream &trace_file)
Doc the solution.
void actions_before_newton_convergence_check()
Update the (enslaved) fluid node positions following the update of the solid variables before perform...
double Nu
Poisson's ratio.
double ReSt
Product of Reynolds and Strouhal numbers (default assignment for FSI1 test case)
bool Ignore_fluid_loading
Ignore fluid (default assignment for FSI1 test case)
double Domain_length
Overall length of domain.
RefineableAlgebraicCylinderWithFlagMesh< FLUID_ELEMENT > * fluid_mesh_pt()
Access function for the fluid mesh.
void gravity(const double &time, const Vector< double > &xi, Vector< double > &b)
Non-dimensional gravity as body force.
double Max_flux
Max. flux.
TurekProblem(const double &length, const double &height)
Constructor: Pass length and height of domain.
SolidMesh * Combined_traction_mesh_pt
Combined mesh of traction elements – only used for documentation.
void actions_after_adapt()
Actions after adapt: Re-setup the fsi lookup scheme.
ConstitutiveLaw * Constitutive_law_pt
Pointer to constitutive law.
double Radius
Radius of cylinder.
double Re
Reynolds number (default assignment for FSI1 test case)