448 const double &height) : Domain_height(height),
449 Domain_length(length)
454 Max_newton_iterations=20;
470 Newmark<2>* flag_time_stepper_pt=
new Newmark<2>;
471 add_time_stepper_pt(flag_time_stepper_pt);
475 Vector<double> origin(2);
484 double l_x=6.0-origin[0];
487 solid_mesh_pt() =
new ElasticRefineableRectangularQuadMesh<SOLID_ELEMENT>(
488 n_x,n_y,l_x,l_y,origin,flag_time_stepper_pt);
491 Z2ErrorEstimator* solid_error_estimator_pt=
new Z2ErrorEstimator;
492 solid_mesh_pt()->spatial_error_estimator_pt()=solid_error_estimator_pt;
496 FiniteElement* el_pt=
solid_mesh_pt()->finite_element_pt(n_x*n_y/2-1);
499 unsigned nnod=el_pt->nnode();
504 std::cout <<
"Coordinates of solid control point "
535 for (
unsigned bound=0;bound<3;bound++)
538 for(
unsigned e=0;e<n_face_element;e++)
541 FSISolidTractionElement<SOLID_ELEMENT,2>* elem_pt=
542 dynamic_cast<FSISolidTractionElement<SOLID_ELEMENT,2>*
>
546 elem_pt->set_boundary_number_in_bulk_mesh(bound);
563 MeshAsGeomObject* tip_flag_pt=
567 MeshAsGeomObject* top_flag_pt=
581 BDF<2>* fluid_time_stepper_pt=
new BDF<2>;
582 add_time_stepper_pt(fluid_time_stepper_pt);
586 new RefineableAlgebraicCylinderWithFlagMesh<FLUID_ELEMENT>
596 fluid_time_stepper_pt);
605 Z2ErrorEstimator* fluid_error_estimator_pt=
new Z2ErrorEstimator;
606 fluid_mesh_pt()->spatial_error_estimator_pt()=fluid_error_estimator_pt;
619 for (
unsigned i=0;i<3;i++)
636 unsigned n_side = mesh_pt()->nboundary_node(3);
639 for(
unsigned i=0;i<n_side;i++)
646 PVDEquationsBase<2>::pin_redundant_nodal_solid_pressures(
654 for(
unsigned ibound=0;ibound<num_bound;ibound++)
657 for (
unsigned inod=0;inod<num_nod;inod++)
673 RefineableNavierStokesEquations<2>::
674 pin_redundant_nodal_pressures(
fluid_mesh_pt()->element_pt());
686 for (
unsigned inod=0;inod<num_nod;inod++)
688 double ycoord =
Fluid_mesh_pt->boundary_node_pt(ibound,inod)->x(1);
690 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(0,uy);
691 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->set_value(1,0.0);
700 for(
unsigned i=0;i<n_element;i++)
703 SOLID_ELEMENT *el_pt =
dynamic_cast<SOLID_ELEMENT*
>(
707 el_pt->constitutive_law_pt() =
724 for (
unsigned e=0;e<nelem;e++)
727 FLUID_ELEMENT* el_pt =
dynamic_cast<FLUID_ELEMENT*
>
754 for(
unsigned ibound=5;ibound<8;ibound++ )
757 for (
unsigned inod=0;inod<num_nod;inod++)
760 set_auxiliary_node_update_fct_pt(
761 FSI_functions::apply_no_slip_on_moving_wall);
769 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
772 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
775 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
784 GMRES<CRDoubleMatrix>* iterative_linear_solver_pt =
785 new GMRES<CRDoubleMatrix>;
788 iterative_linear_solver_pt->max_iter() = 100;
791 iterative_linear_solver_pt->tolerance() = 1.0e-10;
794 linear_solver_pt()=iterative_linear_solver_pt;
797 FSIPreconditioner* prec_pt=
new FSIPreconditioner(
this);
806 prec_pt->use_block_triangular_version_with_fluid_on_solid();
809 iterative_linear_solver_pt->preconditioner_pt()= prec_pt;
818#ifdef OOMPH_HAS_HYPRE
823 Preconditioner* P_matrix_preconditioner_pt =
new HyprePreconditioner;
825 HyprePreconditioner* P_hypre_solver_pt =
826 static_cast<HyprePreconditioner*
>(P_matrix_preconditioner_pt);
830 Hypre_default_settings::
831 set_defaults_for_2D_poisson_problem(P_hypre_solver_pt);
834 prec_pt->navier_stokes_preconditioner_pt()->
835 set_p_preconditioner(P_matrix_preconditioner_pt);
838 P_hypre_solver_pt->disable_doc_time();
844 cout << assign_eqn_numbers() << std::endl;
898 RefineableNavierStokesEquations<2>::
899 unpin_all_pressure_dofs(fluid_mesh_pt()->element_pt());
902 RefineableNavierStokesEquations<2>::
903 pin_redundant_nodal_pressures(fluid_mesh_pt()->element_pt());
906 PVDEquationsBase<2>::
907 unpin_all_solid_pressure_dofs(solid_mesh_pt()->element_pt());
910 PVDEquationsBase<2>::pin_redundant_nodal_solid_pressures(
911 solid_mesh_pt()->element_pt());
921 for(
unsigned ibound=5;ibound<8;ibound++ )
923 unsigned num_nod= Fluid_mesh_pt->nboundary_node(ibound);
924 for (
unsigned inod=0;inod<num_nod;inod++)
926 Fluid_mesh_pt->boundary_node_pt(ibound, inod)->
927 set_auxiliary_node_update_fct_pt(
928 FSI_functions::apply_no_slip_on_moving_wall);
934 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
935 (
this,5,Fluid_mesh_pt,Traction_mesh_pt[0]);
937 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
938 (
this,6,Fluid_mesh_pt,Traction_mesh_pt[2]);
940 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
941 (
this,7,Fluid_mesh_pt,Traction_mesh_pt[1]);
957 std::set<SolidNode*> all_nodes;
960 for (
unsigned b=0;b<3;b++)
963 unsigned n_element = solid_mesh_pt()->nboundary_element(b);
966 for(
unsigned e=0;e<n_element;e++)
969 SOLID_ELEMENT* bulk_elem_pt =
dynamic_cast<SOLID_ELEMENT*
>(
970 solid_mesh_pt()->boundary_element_pt(b,e));
973 int face_index = solid_mesh_pt()->face_index_at_boundary(b,e);
976 Traction_mesh_pt[b]->add_element_pt(
977 new FSISolidTractionElement<SOLID_ELEMENT,2>(bulk_elem_pt,face_index));
982 unsigned nnod=solid_mesh_pt()->nboundary_node(b);
983 for (
unsigned j=0;j<nnod;j++)
985 all_nodes.insert(solid_mesh_pt()->boundary_node_pt(b,j));
990 Combined_traction_mesh_pt=
new SolidMesh(Traction_mesh_pt);
993 for (std::set<SolidNode*>::iterator it=all_nodes.begin();
994 it!=all_nodes.end();it++)
996 Combined_traction_mesh_pt->add_node_pt(*it);
1009 DocInfo& doc_info, ofstream& trace_file)
1022 unsigned n_plot = 5;
1025 snprintf(filename,
sizeof(filename),
"%s/solid_soln%i.dat",doc_info.directory().c_str(),
1027 some_file.open(filename);
1028 solid_mesh_pt()->output(some_file,n_plot);
1032 snprintf(filename,
sizeof(filename),
"%s/soln%i.dat",doc_info.directory().c_str(),
1034 some_file.open(filename);
1035 fluid_mesh_pt()->output(some_file,n_plot);
1040 snprintf(filename,
sizeof(filename),
"%s/traction%i.dat",doc_info.directory().c_str(),
1042 some_file.open(filename);
1044 for(
unsigned i=0;i<3;i++)
1047 unsigned n_element = Traction_mesh_pt[i]->nelement();
1048 for(
unsigned e=0;e<n_element;e++)
1050 FSISolidTractionElement<SOLID_ELEMENT,2>* el_pt =
1051 dynamic_cast<FSISolidTractionElement<SOLID_ELEMENT,2>*
> (
1052 Traction_mesh_pt[i]->element_pt(e) );
1054 el_pt->output(some_file,5);
1062 trace_file << time_pt()->time() <<
" "
1063 << Solid_control_node_pt->x(0) <<
" "
1064 << Solid_control_node_pt->x(1) <<
" "
1065 << Fluid_control_node_pt->value(2) <<
" "
1069 cout <<
"Doced solution for step "
1070 << doc_info.number()
1071 << std::endl << std::endl << std::endl;
1083 CommandLineArgs::setup(argc,argv);
1086 string case_id=
"FSI1";
1087 if (CommandLineArgs::Argc==1)
1089 oomph_info <<
"No command line arguments; running self-test FSI1"
1092 else if (CommandLineArgs::Argc==2)
1094 case_id=CommandLineArgs::Argv[1];
1098 oomph_info <<
"Wrong number of command line arguments" << std::endl;
1099 oomph_info <<
"Enter none (for default) or one (namely the case id"
1101 oomph_info <<
"which should be one of: FSI1, FSI2, FSI3, CSM1"
1104 std::cout <<
"Running case " << case_id << std::endl;
1112 ofstream trace_file;
1113 doc_info.set_directory(
"RESLT");
1114 trace_file.open(
"RESLT/trace.dat");
1122 RefineableQPVDElement<2,3> > problem(length, height);
1125 unsigned nstep=4000;
1128 std::cout <<
"Reducing number of steps for FSI1 " << std::endl;
1132 if (CommandLineArgs::Argc==1)
1134 std::cout <<
"Reducing number of steps for validation " << std::endl;
1142 problem.initialise_dt(dt);
1145 problem.assign_initial_values_impulsive(dt);
1149 doc_info.number()++;
1156 unsigned max_adapt=1;
1158 for(
unsigned i=0;i<nstep;i++)
1161 problem.unsteady_newton_solve(dt,max_adapt,first);
1167 doc_info.number()++;