37 #include "constitutive.h" 38 #include "navier_stokes.h" 41 #include "meshes/tetgen_mesh.h" 44 using namespace oomph;
51 template<
class ELEMENT>
53 public virtual SolidMesh
60 const std::string& element_file_name,
61 const std::string& face_file_name,
62 TimeStepper* time_stepper_pt=
63 &Mesh::Default_TimeStepper) :
64 TetgenMesh<ELEMENT>(node_file_name, element_file_name,
65 face_file_name, time_stepper_pt)
68 set_lagrangian_nodal_coordinates();
71 setup_boundary_element_info();
76 unsigned nb=this->nboundary();
77 for (
unsigned b=0;b<nb;b++)
79 sprintf(filename,
"RESLT/solid_boundary_test%i.dat",b);
80 some_file.open(filename);
81 this->
template setup_boundary_coordinates<ELEMENT>(b,some_file);
101 template<
class ELEMENT>
103 public virtual SolidMesh
110 const std::string& element_file_name,
111 const std::string& face_file_name,
112 const bool& split_corner_elements,
113 TimeStepper* time_stepper_pt=
114 &Mesh::Default_TimeStepper) :
115 TetgenMesh<ELEMENT>(node_file_name, element_file_name,
116 face_file_name, split_corner_elements,
120 set_lagrangian_nodal_coordinates();
123 setup_boundary_element_info();
130 bool switch_normal=
true;
135 unsigned nb=this->nboundary();
136 for (
unsigned b=0;b<nb;b++)
138 sprintf(filename,
"RESLT/fluid_boundary_test%i.dat",b);
139 some_file.open(filename);
140 this->
template setup_boundary_coordinates<ELEMENT>(b,switch_normal,some_file);
180 const Vector<double>& x,
181 const Vector<double>& n,
182 Vector<double>& traction)
195 const Vector<double>& x,
196 const Vector<double>& n,
197 Vector<double>& traction)
215 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
228 void doc_solution(DocInfo& doc_info);
231 void create_fluid_traction_elements();
234 void create_fsi_traction_elements();
238 void create_lagrange_multiplier_elements();
244 void doc_solid_boundary_coordinates(
const unsigned& i);
249 {
return Inflow_boundary_id.size();}
254 {
return Outflow_boundary_id.size();}
259 {
return Inflow_boundary_id.size()+Outflow_boundary_id.size();}
264 {
return Solid_fsi_boundary_id.size();}
269 {
return Fluid_fsi_boundary_id.size();}
274 {
return Pinned_solid_boundary_id.size();}
294 Vector<MeshAsGeomObject*>
321 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
328 string node_file_name=
"fsi_bifurcation_fluid.1.node";
329 string element_file_name=
"fsi_bifurcation_fluid.1.ele";
330 string face_file_name=
"fsi_bifurcation_fluid.1.face";
331 bool split_corner_elements=
true;
335 split_corner_elements);
342 Inflow_boundary_id.resize(1);
343 Inflow_boundary_id[0]=0;
346 Outflow_boundary_id.resize(2);
347 Outflow_boundary_id[0]=1;
348 Outflow_boundary_id[1]=2;
354 Fluid_fsi_boundary_id.resize(12);
355 for (
unsigned i=0;i<12;i++)
357 Fluid_fsi_boundary_id[i]=i+3;
365 node_file_name=
"fsi_bifurcation_solid.1.node";
366 element_file_name=
"fsi_bifurcation_solid.1.ele";
367 face_file_name=
"fsi_bifurcation_solid.1.face";
376 Pinned_solid_boundary_id.resize(3);
377 Pinned_solid_boundary_id[0]=0;
378 Pinned_solid_boundary_id[1]=1;
379 Pinned_solid_boundary_id[2]=2;
382 Solid_fsi_boundary_id.resize(12);
383 for (
unsigned i=0;i<12;i++)
385 Solid_fsi_boundary_id[i]=i+3;
394 unsigned n=nfluid_traction_boundary();
395 Fluid_traction_mesh_pt.resize(n);
396 for (
unsigned i=0;i<n;i++)
398 Fluid_traction_mesh_pt[i]=
new Mesh;
402 create_fluid_traction_elements();
409 n=nsolid_fsi_boundary();
410 Solid_fsi_traction_mesh_pt.resize(n);
411 for (
unsigned i=0;i<n;i++)
413 Solid_fsi_traction_mesh_pt[i]=
new SolidMesh;
417 create_fsi_traction_elements();
425 n=nfluid_fsi_boundary();
426 Lagrange_multiplier_mesh_pt.resize(n);
427 for (
unsigned i=0;i<n;i++)
429 Lagrange_multiplier_mesh_pt[i]=
new SolidMesh;
433 create_lagrange_multiplier_elements();
442 add_sub_mesh(Solid_mesh_pt);
445 add_sub_mesh(Fluid_mesh_pt);
448 n=nfluid_traction_boundary();
449 for (
unsigned i=0;i<n;i++)
451 add_sub_mesh(Fluid_traction_mesh_pt[i]);
455 n=nsolid_fsi_boundary();
456 for (
unsigned i=0;i<n;i++)
458 add_sub_mesh(Solid_fsi_traction_mesh_pt[i]);
462 n=nfluid_fsi_boundary();
463 for (
unsigned i=0;i<n;i++)
465 add_sub_mesh(Lagrange_multiplier_mesh_pt[i]);
478 std::ofstream pseudo_solid_bc_file(
"RESLT/pinned_pseudo_solid_nodes.dat");
482 for (
unsigned in_out=0;in_out<2;in_out++)
485 unsigned n=nfluid_inflow_traction_boundary();
486 if (in_out==1) n=nfluid_outflow_traction_boundary();
487 for (
unsigned i=0;i<n;i++)
494 b=Inflow_boundary_id[i];
498 b=Outflow_boundary_id[i];
502 unsigned num_nod=Fluid_mesh_pt->nboundary_node(b);
503 for (
unsigned inod=0;inod<num_nod;inod++)
506 SolidNode* nod_pt=Fluid_mesh_pt->boundary_node_pt(b,inod);
513 for(
unsigned i=0;i<3;i++)
515 nod_pt->pin_position(i);
518 pseudo_solid_bc_file << nod_pt->x(i) <<
" ";
525 pseudo_solid_bc_file.close();
528 ofstream pinned_file(
"RESLT/pinned_lagrange_multiplier_nodes.dat");
532 unsigned nbound=nfluid_fsi_boundary();
533 for(
unsigned i=0;i<nbound;i++)
536 unsigned b = Fluid_fsi_boundary_id[i];
538 unsigned num_nod=Fluid_mesh_pt->nboundary_node(b);
539 for (
unsigned inod=0;inod<num_nod;inod++)
542 Node* nod_pt= Fluid_mesh_pt->boundary_node_pt(b,inod);
550 bool is_in_or_outflow_node=
false;
551 unsigned n=nfluid_inflow_traction_boundary();
552 for (
unsigned k=0;k<n;k++)
554 if (nod_pt->is_on_boundary(Inflow_boundary_id[k]))
556 is_in_or_outflow_node=
true;
560 if (!is_in_or_outflow_node)
562 unsigned n=nfluid_outflow_traction_boundary();
563 for (
unsigned k=0;k<n;k++)
565 if (nod_pt->is_on_boundary(Outflow_boundary_id[k]))
567 is_in_or_outflow_node=
true;
574 if (is_in_or_outflow_node)
577 BoundaryNode<SolidNode> *bnod_pt =
578 dynamic_cast<BoundaryNode<SolidNode>*
> 579 ( Fluid_mesh_pt->boundary_node_pt(b,inod) );
582 for (
unsigned l=0;l<3;l++)
588 (bnod_pt->index_of_first_value_assigned_by_face_element()+l);
592 pinned_file << nod_pt->x(0) <<
" " 593 << nod_pt->x(1) <<
" " 594 << nod_pt->x(2) << endl;
605 unsigned n_element = Fluid_mesh_pt->nelement();
606 for(
unsigned e=0;e<n_element;e++)
609 FLUID_ELEMENT* el_pt =
610 dynamic_cast<FLUID_ELEMENT*
>(Fluid_mesh_pt->element_pt(e));
616 el_pt->constitutive_law_pt() =
627 std::ofstream bc_file(
"RESLT/pinned_solid_nodes.dat");
630 n=npinned_solid_boundary();
631 for (
unsigned i=0;i<n;i++)
634 unsigned b=Pinned_solid_boundary_id[i];
635 unsigned num_nod= Solid_mesh_pt->nboundary_node(b);
636 for (
unsigned inod=0;inod<num_nod;inod++)
639 SolidNode* nod_pt=Solid_mesh_pt->boundary_node_pt(b,inod);
642 for (
unsigned i=0;i<3;i++)
644 nod_pt->pin_position(i);
647 bc_file << nod_pt->x(i) <<
" ";
650 bc_file << std::endl;
659 n_element = Solid_mesh_pt->nelement();
660 for(
unsigned i=0;i<n_element;i++)
663 SOLID_ELEMENT *el_pt =
dynamic_cast<SOLID_ELEMENT*
>(
664 Solid_mesh_pt->element_pt(i));
667 el_pt->constitutive_law_pt() =
678 n=nsolid_fsi_boundary();
679 for (
unsigned i=0;i<n;i++)
682 doc_solid_boundary_coordinates(i);
686 sprintf(filename,
"RESLT/fluid_boundary_coordinates%i.dat",i);
687 Multi_domain_functions::Doc_boundary_coordinate_file.open(filename);
691 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,3>
692 (
this,Fluid_fsi_boundary_id[i],Fluid_mesh_pt,Solid_fsi_traction_mesh_pt[i]);
695 Multi_domain_functions::Doc_boundary_coordinate_file.close();
699 std::cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
707 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
713 unsigned n=nsolid_fsi_boundary();
714 for (
unsigned i=0;i<n;i++)
717 unsigned b=Solid_fsi_boundary_id[i];
720 unsigned n_element = Solid_mesh_pt->nboundary_element(b);
723 for(
unsigned e=0;e<n_element;e++)
726 SOLID_ELEMENT* bulk_elem_pt =
dynamic_cast<SOLID_ELEMENT*
>(
727 Solid_mesh_pt->boundary_element_pt(b,e));
730 int face_index = Solid_mesh_pt->face_index_at_boundary(b,e);
733 FSISolidTractionElement<SOLID_ELEMENT,3>* el_pt=
734 new FSISolidTractionElement<SOLID_ELEMENT,3>(bulk_elem_pt,face_index);
737 Solid_fsi_traction_mesh_pt[i]->add_element_pt(el_pt);
740 el_pt->set_boundary_number_in_bulk_mesh(b);
754 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
759 unsigned n=nfluid_fsi_boundary();
760 Solid_fsi_boundary_pt.resize(n);
763 for (
unsigned i=0;i<n;i++)
766 unsigned b=Fluid_fsi_boundary_id[i];
769 Solid_fsi_boundary_pt[i]=
771 (Solid_fsi_traction_mesh_pt[i]);
774 unsigned n_element = Fluid_mesh_pt->nboundary_element(b);
777 for(
unsigned e=0;e<n_element;e++)
780 FLUID_ELEMENT* bulk_elem_pt =
dynamic_cast<FLUID_ELEMENT*
>(
781 Fluid_mesh_pt->boundary_element_pt(b,e));
784 int face_index = Fluid_mesh_pt->face_index_at_boundary(b,e);
787 ImposeDisplacementByLagrangeMultiplierElement<FLUID_ELEMENT>* el_pt =
788 new ImposeDisplacementByLagrangeMultiplierElement<FLUID_ELEMENT>(
789 bulk_elem_pt,face_index);
792 Lagrange_multiplier_mesh_pt[i]->add_element_pt(el_pt);
797 el_pt->set_boundary_shape_geom_object_pt(Solid_fsi_boundary_pt[i],b);
808 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
817 for (
unsigned in_out=0;in_out<2;in_out++)
820 unsigned n=nfluid_inflow_traction_boundary();
821 if (in_out==1) n=nfluid_outflow_traction_boundary();
822 for (
unsigned i=0;i<n;i++)
829 b=Inflow_boundary_id[i];
833 b=Outflow_boundary_id[i];
837 unsigned n_element = Fluid_mesh_pt->nboundary_element(b);
840 for(
unsigned e=0;e<n_element;e++)
843 FLUID_ELEMENT* bulk_elem_pt =
dynamic_cast<FLUID_ELEMENT*
>(
844 Fluid_mesh_pt->boundary_element_pt(b,e));
847 int face_index = Fluid_mesh_pt->face_index_at_boundary(b,e);
850 NavierStokesTractionElement<FLUID_ELEMENT>* el_pt=
851 new NavierStokesTractionElement<FLUID_ELEMENT>(bulk_elem_pt,
855 Fluid_traction_mesh_pt[count]->add_element_pt(el_pt);
860 el_pt->traction_fct_pt() =
865 el_pt->traction_fct_pt() =
880 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
887 sprintf(filename,
"RESLT/solid_boundary_coordinates%i.dat",i);
888 std::ofstream the_file(filename);
891 unsigned n_face_element = Solid_fsi_traction_mesh_pt[i]->nelement();
892 for(
unsigned e=0;e<n_face_element;e++)
895 FSISolidTractionElement<SOLID_ELEMENT,3>* el_pt=
896 dynamic_cast<FSISolidTractionElement<SOLID_ELEMENT,3>*
> 897 (Solid_fsi_traction_mesh_pt[i]->element_pt(e));
901 Vector<double> zeta(2);
904 the_file << el_pt->tecplot_zone_string(n_plot);
907 unsigned num_plot_points=el_pt->nplot_points(n_plot);
908 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
911 el_pt->get_s_plot(iplot,n_plot,s);
912 el_pt->interpolated_zeta(s,zeta);
913 el_pt->interpolated_x(s,x);
914 for (
unsigned i=0;i<3;i++)
916 the_file << x[i] <<
" ";
918 for (
unsigned i=0;i<2;i++)
920 the_file << zeta[i] <<
" ";
923 the_file << std::endl;
925 el_pt->write_tecplot_zone_footer(the_file,n_plot);
937 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
951 sprintf(filename,
"%s/solid_boundaries%i.dat",doc_info.directory().c_str(),
953 some_file.open(filename);
954 Solid_mesh_pt->output_boundaries(some_file);
960 sprintf(filename,
"%s/solid_soln%i.dat",doc_info.directory().c_str(),
962 some_file.open(filename);
963 Solid_mesh_pt->output(some_file,npts);
969 sprintf(filename,
"%s/fluid_boundaries%i.dat",doc_info.directory().c_str(),
971 some_file.open(filename);
972 Fluid_mesh_pt->output_boundaries(some_file);
978 sprintf(filename,
"%s/fluid_soln%i.dat",doc_info.directory().c_str(),
980 some_file.open(filename);
981 Fluid_mesh_pt->output(some_file,npts);
987 sprintf(filename,
"%s/fsi_traction%i.dat",doc_info.directory().c_str(),
989 some_file.open(filename);
990 unsigned n=nsolid_fsi_boundary();
991 for (
unsigned i=0;i<n;i++)
993 Solid_fsi_traction_mesh_pt[i]->output(some_file,npts);
1012 doc_info.set_directory(
"RESLT");
1020 PseudoSolidNodeUpdateElement<TTaylorHoodElement<3>, TPVDElement<3,3> >,
1021 TPVDElement<3,3> > problem;
1025 doc_info.number()++;
1031 double q_increment=5.0e-2;
1033 for (
unsigned istep=0;istep<nstep;istep++)
1036 problem.newton_solve();
1039 problem.doc_solution(doc_info);
1040 doc_info.number()++;
Vector< SolidMesh * > Lagrange_multiplier_mesh_pt
Meshes of Lagrange multiplier elements.
double Q
Default FSI parameter.
UnstructuredFSIProblem()
Constructor:
unsigned nsolid_fsi_boundary()
Return total number of mesh boundaries in the solid mesh that make up the FSI interface.
Vector< MeshAsGeomObject * > Solid_fsi_boundary_pt
GeomObject incarnations of the FSI boundary in the solid mesh.
MySolidTetgenMesh< SOLID_ELEMENT > * Solid_mesh_pt
Bulk solid mesh.
MySolidTetgenMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &face_file_name, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor:
double P_in
Fluid pressure on inflow boundary.
void prescribed_inflow_traction(const double &t, const Vector< double > &x, const Vector< double > &n, Vector< double > &traction)
Applied traction on fluid at the inflow boundary.
Vector< SolidMesh * > Solid_fsi_traction_mesh_pt
Meshes of FSI traction elements.
void create_fluid_traction_elements()
Create fluid traction elements at inflow.
virtual ~MySolidTetgenMesh()
Empty Destructor.
void create_fsi_traction_elements()
Create FSI traction elements.
int main(int argc, char **argv)
Demonstrate how to solve an unstructured 3D FSI problem.
~UnstructuredFSIProblem()
Destructor (empty)
Vector< unsigned > Solid_fsi_boundary_id
IDs of solid mesh boundaries which make up the FSI interface.
unsigned nfluid_inflow_traction_boundary()
Return total number of mesh boundaries that make up the inflow boundary.
void doc_solution(DocInfo &doc_info)
Doc the solution.
Vector< unsigned > Fluid_fsi_boundary_id
IDs of fluid mesh boundaries which make up the FSI interface.
Unstructured 3D FSI problem.
virtual ~FluidTetMesh()
Empty Destructor.
void prescribed_outflow_traction(const double &t, const Vector< double > &x, const Vector< double > &n, Vector< double > &traction)
Applied traction on fluid at the inflow boundary.
double P_out
Fluid pressure on outflow boundary.
FluidTetMesh< FLUID_ELEMENT > * Fluid_mesh_pt
Bulk fluid mesh.
unsigned npinned_solid_boundary()
Return total number of mesh boundaries in the solid mesh where the position is pinned.
Vector< unsigned > Outflow_boundary_id
IDs of fluid mesh boundaries along which inflow boundary conditions are applied.
double Nu
Poisson's ratio for generalised Hookean constitutive equation.
Tetgen-based mesh upgraded to become a (pseudo-) solid mesh.
Vector< Mesh * > Fluid_traction_mesh_pt
Meshes of fluid traction elements that apply pressure at in/outflow.
unsigned nfluid_fsi_boundary()
Return total number of mesh boundaries in the fluid mesh that make up the FSI interface.
unsigned nfluid_traction_boundary()
Return total number of mesh boundaries that make up the in- and outflow boundaries where a traction h...
void create_lagrange_multiplier_elements()
Create elements that enforce prescribed boundary motion for the pseudo-solid fluid mesh by Lagrange m...
FluidTetMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &face_file_name, const bool &split_corner_elements, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor:
Vector< unsigned > Inflow_boundary_id
IDs of fluid mesh boundaries along which inflow boundary conditions are applied.
Tetgen-based mesh upgraded to become a solid mesh.
ConstitutiveLaw * Constitutive_law_pt
Pointer to constitutive law.
double Re
Default Reynolds number.
void doc_solid_boundary_coordinates(const unsigned &i)
Sanity check: Doc boundary coordinates on i-th solid FSI interface.
Vector< unsigned > Pinned_solid_boundary_id
IDs of solid mesh boundaries where displacements are pinned.
unsigned nfluid_outflow_traction_boundary()
Return total number of mesh boundaries that make up the outflow boundary.