33 #include "constitutive.h"
34 #include "navier_stokes.h"
37 #include "meshes/tetgen_mesh.h"
40 using namespace oomph;
47 template<
class ELEMENT>
49 public virtual SolidMesh
56 const std::string& element_file_name,
57 const std::string& face_file_name,
58 TimeStepper* time_stepper_pt=
59 &Mesh::Default_TimeStepper) :
60 TetgenMesh<ELEMENT>(node_file_name, element_file_name,
61 face_file_name, time_stepper_pt)
64 set_lagrangian_nodal_coordinates();
67 setup_boundary_element_info();
72 unsigned nb=this->nboundary();
73 for (
unsigned b=0;b<nb;b++)
75 sprintf(filename,
"RESLT/solid_boundary_test%i.dat",b);
76 some_file.open(filename);
77 this->
template setup_boundary_coordinates<ELEMENT>(b,some_file);
97 template<
class ELEMENT>
99 public virtual SolidMesh
106 const std::string& element_file_name,
107 const std::string& face_file_name,
108 const bool& split_corner_elements,
109 TimeStepper* time_stepper_pt=
110 &Mesh::Default_TimeStepper) :
111 TetgenMesh<ELEMENT>(node_file_name, element_file_name,
112 face_file_name, split_corner_elements,
116 set_lagrangian_nodal_coordinates();
119 setup_boundary_element_info();
126 bool switch_normal=
true;
131 unsigned nb=this->nboundary();
132 for (
unsigned b=0;b<nb;b++)
134 sprintf(filename,
"RESLT/fluid_boundary_test%i.dat",b);
135 some_file.open(filename);
136 this->
template setup_boundary_coordinates<ELEMENT>(b,switch_normal,some_file);
176 const Vector<double>& x,
177 const Vector<double>& n,
178 Vector<double>& traction)
191 const Vector<double>& x,
192 const Vector<double>& n,
193 Vector<double>& traction)
211 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
224 void doc_solution(DocInfo& doc_info);
227 void create_fluid_traction_elements();
230 void create_fsi_traction_elements();
234 void create_lagrange_multiplier_elements();
240 void doc_solid_boundary_coordinates(
const unsigned& i);
245 {
return Inflow_boundary_id.size();}
250 {
return Outflow_boundary_id.size();}
255 {
return Inflow_boundary_id.size()+Outflow_boundary_id.size();}
260 {
return Solid_fsi_boundary_id.size();}
265 {
return Fluid_fsi_boundary_id.size();}
270 {
return Pinned_solid_boundary_id.size();}
290 Vector<MeshAsGeomObject*>
317 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
324 string node_file_name=
"fsi_bifurcation_fluid.1.node";
325 string element_file_name=
"fsi_bifurcation_fluid.1.ele";
326 string face_file_name=
"fsi_bifurcation_fluid.1.face";
327 bool split_corner_elements=
true;
331 split_corner_elements);
338 Inflow_boundary_id.resize(1);
339 Inflow_boundary_id[0]=0;
342 Outflow_boundary_id.resize(2);
343 Outflow_boundary_id[0]=1;
344 Outflow_boundary_id[1]=2;
350 Fluid_fsi_boundary_id.resize(12);
351 for (
unsigned i=0;i<12;i++)
353 Fluid_fsi_boundary_id[i]=i+3;
361 node_file_name=
"fsi_bifurcation_solid.1.node";
362 element_file_name=
"fsi_bifurcation_solid.1.ele";
363 face_file_name=
"fsi_bifurcation_solid.1.face";
372 Pinned_solid_boundary_id.resize(3);
373 Pinned_solid_boundary_id[0]=0;
374 Pinned_solid_boundary_id[1]=1;
375 Pinned_solid_boundary_id[2]=2;
378 Solid_fsi_boundary_id.resize(12);
379 for (
unsigned i=0;i<12;i++)
381 Solid_fsi_boundary_id[i]=i+3;
390 unsigned n=nfluid_traction_boundary();
391 Fluid_traction_mesh_pt.resize(n);
392 for (
unsigned i=0;i<n;i++)
394 Fluid_traction_mesh_pt[i]=
new Mesh;
398 create_fluid_traction_elements();
405 n=nsolid_fsi_boundary();
406 Solid_fsi_traction_mesh_pt.resize(n);
407 for (
unsigned i=0;i<n;i++)
409 Solid_fsi_traction_mesh_pt[i]=
new SolidMesh;
413 create_fsi_traction_elements();
421 n=nfluid_fsi_boundary();
422 Lagrange_multiplier_mesh_pt.resize(n);
423 for (
unsigned i=0;i<n;i++)
425 Lagrange_multiplier_mesh_pt[i]=
new SolidMesh;
429 create_lagrange_multiplier_elements();
438 add_sub_mesh(Solid_mesh_pt);
441 add_sub_mesh(Fluid_mesh_pt);
444 n=nfluid_traction_boundary();
445 for (
unsigned i=0;i<n;i++)
447 add_sub_mesh(Fluid_traction_mesh_pt[i]);
451 n=nsolid_fsi_boundary();
452 for (
unsigned i=0;i<n;i++)
454 add_sub_mesh(Solid_fsi_traction_mesh_pt[i]);
458 n=nfluid_fsi_boundary();
459 for (
unsigned i=0;i<n;i++)
461 add_sub_mesh(Lagrange_multiplier_mesh_pt[i]);
474 std::ofstream pseudo_solid_bc_file(
"RESLT/pinned_pseudo_solid_nodes.dat");
478 for (
unsigned in_out=0;in_out<2;in_out++)
481 unsigned n=nfluid_inflow_traction_boundary();
482 if (in_out==1) n=nfluid_outflow_traction_boundary();
483 for (
unsigned i=0;i<n;i++)
490 b=Inflow_boundary_id[i];
494 b=Outflow_boundary_id[i];
498 unsigned num_nod=Fluid_mesh_pt->nboundary_node(b);
499 for (
unsigned inod=0;inod<num_nod;inod++)
502 SolidNode* nod_pt=Fluid_mesh_pt->boundary_node_pt(b,inod);
509 for(
unsigned i=0;i<3;i++)
511 nod_pt->pin_position(i);
514 pseudo_solid_bc_file << nod_pt->x(i) <<
" ";
521 pseudo_solid_bc_file.close();
524 ofstream pinned_file(
"RESLT/pinned_lagrange_multiplier_nodes.dat");
528 unsigned nbound=nfluid_fsi_boundary();
529 for(
unsigned i=0;i<nbound;i++)
532 unsigned b = Fluid_fsi_boundary_id[i];
534 unsigned num_nod=Fluid_mesh_pt->nboundary_node(b);
535 for (
unsigned inod=0;inod<num_nod;inod++)
538 Node* nod_pt= Fluid_mesh_pt->boundary_node_pt(b,inod);
546 bool is_in_or_outflow_node=
false;
547 unsigned n=nfluid_inflow_traction_boundary();
548 for (
unsigned k=0;k<n;k++)
550 if (nod_pt->is_on_boundary(Inflow_boundary_id[k]))
552 is_in_or_outflow_node=
true;
556 if (!is_in_or_outflow_node)
558 unsigned n=nfluid_outflow_traction_boundary();
559 for (
unsigned k=0;k<n;k++)
561 if (nod_pt->is_on_boundary(Outflow_boundary_id[k]))
563 is_in_or_outflow_node=
true;
570 if (is_in_or_outflow_node)
573 BoundaryNode<SolidNode> *bnod_pt =
574 dynamic_cast<BoundaryNode<SolidNode>*
>
575 ( Fluid_mesh_pt->boundary_node_pt(b,inod) );
578 for (
unsigned l=0;l<3;l++)
584 (bnod_pt->index_of_first_value_assigned_by_face_element()+l);
588 pinned_file << nod_pt->x(0) <<
" "
589 << nod_pt->x(1) <<
" "
590 << nod_pt->x(2) << endl;
601 unsigned n_element = Fluid_mesh_pt->nelement();
602 for(
unsigned e=0;e<n_element;e++)
605 FLUID_ELEMENT* el_pt =
606 dynamic_cast<FLUID_ELEMENT*
>(Fluid_mesh_pt->element_pt(e));
612 el_pt->constitutive_law_pt() =
623 std::ofstream bc_file(
"RESLT/pinned_solid_nodes.dat");
626 n=npinned_solid_boundary();
627 for (
unsigned i=0;i<n;i++)
630 unsigned b=Pinned_solid_boundary_id[i];
631 unsigned num_nod= Solid_mesh_pt->nboundary_node(b);
632 for (
unsigned inod=0;inod<num_nod;inod++)
635 SolidNode* nod_pt=Solid_mesh_pt->boundary_node_pt(b,inod);
638 for (
unsigned i=0;i<3;i++)
640 nod_pt->pin_position(i);
643 bc_file << nod_pt->x(i) <<
" ";
646 bc_file << std::endl;
655 n_element = Solid_mesh_pt->nelement();
656 for(
unsigned i=0;i<n_element;i++)
659 SOLID_ELEMENT *el_pt =
dynamic_cast<SOLID_ELEMENT*
>(
660 Solid_mesh_pt->element_pt(i));
663 el_pt->constitutive_law_pt() =
674 n=nsolid_fsi_boundary();
675 for (
unsigned i=0;i<n;i++)
678 doc_solid_boundary_coordinates(i);
682 sprintf(filename,
"RESLT/fluid_boundary_coordinates%i.dat",i);
683 Multi_domain_functions::Doc_boundary_coordinate_file.open(filename);
687 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,3>
688 (
this,Fluid_fsi_boundary_id[i],Fluid_mesh_pt,Solid_fsi_traction_mesh_pt[i]);
691 Multi_domain_functions::Doc_boundary_coordinate_file.close();
695 std::cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
703 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
709 unsigned n=nsolid_fsi_boundary();
710 for (
unsigned i=0;i<n;i++)
713 unsigned b=Solid_fsi_boundary_id[i];
716 unsigned n_element = Solid_mesh_pt->nboundary_element(b);
719 for(
unsigned e=0;e<n_element;e++)
722 SOLID_ELEMENT* bulk_elem_pt =
dynamic_cast<SOLID_ELEMENT*
>(
723 Solid_mesh_pt->boundary_element_pt(b,e));
726 int face_index = Solid_mesh_pt->face_index_at_boundary(b,e);
729 FSISolidTractionElement<SOLID_ELEMENT,3>* el_pt=
730 new FSISolidTractionElement<SOLID_ELEMENT,3>(bulk_elem_pt,face_index);
733 Solid_fsi_traction_mesh_pt[i]->add_element_pt(el_pt);
736 el_pt->set_boundary_number_in_bulk_mesh(b);
750 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
755 unsigned n=nfluid_fsi_boundary();
756 Solid_fsi_boundary_pt.resize(n);
759 for (
unsigned i=0;i<n;i++)
762 unsigned b=Fluid_fsi_boundary_id[i];
765 Solid_fsi_boundary_pt[i]=
767 (Solid_fsi_traction_mesh_pt[i]);
770 unsigned n_element = Fluid_mesh_pt->nboundary_element(b);
773 for(
unsigned e=0;e<n_element;e++)
776 FLUID_ELEMENT* bulk_elem_pt =
dynamic_cast<FLUID_ELEMENT*
>(
777 Fluid_mesh_pt->boundary_element_pt(b,e));
780 int face_index = Fluid_mesh_pt->face_index_at_boundary(b,e);
783 ImposeDisplacementByLagrangeMultiplierElement<FLUID_ELEMENT>* el_pt =
784 new ImposeDisplacementByLagrangeMultiplierElement<FLUID_ELEMENT>(
785 bulk_elem_pt,face_index);
788 Lagrange_multiplier_mesh_pt[i]->add_element_pt(el_pt);
793 el_pt->set_boundary_shape_geom_object_pt(Solid_fsi_boundary_pt[i],b);
804 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
813 for (
unsigned in_out=0;in_out<2;in_out++)
816 unsigned n=nfluid_inflow_traction_boundary();
817 if (in_out==1) n=nfluid_outflow_traction_boundary();
818 for (
unsigned i=0;i<n;i++)
825 b=Inflow_boundary_id[i];
829 b=Outflow_boundary_id[i];
833 unsigned n_element = Fluid_mesh_pt->nboundary_element(b);
836 for(
unsigned e=0;e<n_element;e++)
839 FLUID_ELEMENT* bulk_elem_pt =
dynamic_cast<FLUID_ELEMENT*
>(
840 Fluid_mesh_pt->boundary_element_pt(b,e));
843 int face_index = Fluid_mesh_pt->face_index_at_boundary(b,e);
846 NavierStokesTractionElement<FLUID_ELEMENT>* el_pt=
847 new NavierStokesTractionElement<FLUID_ELEMENT>(bulk_elem_pt,
851 Fluid_traction_mesh_pt[count]->add_element_pt(el_pt);
856 el_pt->traction_fct_pt() =
861 el_pt->traction_fct_pt() =
876 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
883 sprintf(filename,
"RESLT/solid_boundary_coordinates%i.dat",i);
884 std::ofstream the_file(filename);
887 unsigned n_face_element = Solid_fsi_traction_mesh_pt[i]->nelement();
888 for(
unsigned e=0;e<n_face_element;e++)
891 FSISolidTractionElement<SOLID_ELEMENT,3>* el_pt=
892 dynamic_cast<FSISolidTractionElement<SOLID_ELEMENT,3>*
>
893 (Solid_fsi_traction_mesh_pt[i]->element_pt(e));
897 Vector<double> zeta(2);
900 the_file << el_pt->tecplot_zone_string(n_plot);
903 unsigned num_plot_points=el_pt->nplot_points(n_plot);
904 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
907 el_pt->get_s_plot(iplot,n_plot,s);
908 el_pt->interpolated_zeta(s,zeta);
909 el_pt->interpolated_x(s,x);
910 for (
unsigned i=0;i<3;i++)
912 the_file << x[i] <<
" ";
914 for (
unsigned i=0;i<2;i++)
916 the_file << zeta[i] <<
" ";
919 the_file << std::endl;
921 el_pt->write_tecplot_zone_footer(the_file,n_plot);
933 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
947 sprintf(filename,
"%s/solid_boundaries%i.dat",doc_info.directory().c_str(),
949 some_file.open(filename);
950 Solid_mesh_pt->output_boundaries(some_file);
956 sprintf(filename,
"%s/solid_soln%i.dat",doc_info.directory().c_str(),
958 some_file.open(filename);
959 Solid_mesh_pt->output(some_file,npts);
965 sprintf(filename,
"%s/fluid_boundaries%i.dat",doc_info.directory().c_str(),
967 some_file.open(filename);
968 Fluid_mesh_pt->output_boundaries(some_file);
974 sprintf(filename,
"%s/fluid_soln%i.dat",doc_info.directory().c_str(),
976 some_file.open(filename);
977 Fluid_mesh_pt->output(some_file,npts);
983 sprintf(filename,
"%s/fsi_traction%i.dat",doc_info.directory().c_str(),
985 some_file.open(filename);
986 unsigned n=nsolid_fsi_boundary();
987 for (
unsigned i=0;i<n;i++)
989 Solid_fsi_traction_mesh_pt[i]->output(some_file,npts);
1008 doc_info.set_directory(
"RESLT");
1016 PseudoSolidNodeUpdateElement<TTaylorHoodElement<3>, TPVDElement<3,3> >,
1017 TPVDElement<3,3> > problem;
1021 doc_info.number()++;
1027 double q_increment=5.0e-2;
1029 for (
unsigned istep=0;istep<nstep;istep++)
1032 problem.newton_solve();
1035 problem.doc_solution(doc_info);
1036 doc_info.number()++;
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
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:
virtual ~FluidTetMesh()
Empty Destructor.
Tetgen-based mesh upgraded to become a 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:
virtual ~MySolidTetgenMesh()
Empty Destructor.
Unstructured 3D FSI problem.
void doc_solution(DocInfo &doc_info)
Doc the solution.
Vector< Mesh * > Fluid_traction_mesh_pt
Meshes of fluid traction elements that apply pressure at in/outflow.
unsigned npinned_solid_boundary()
Return total number of mesh boundaries in the solid mesh where the position is pinned.
Vector< unsigned > Solid_fsi_boundary_id
IDs of solid mesh boundaries which make up the FSI interface.
Vector< MeshAsGeomObject * > Solid_fsi_boundary_pt
GeomObject incarnations of the FSI boundary in the solid mesh.
Vector< SolidMesh * > Lagrange_multiplier_mesh_pt
Meshes of Lagrange multiplier elements.
unsigned nsolid_fsi_boundary()
Return total number of mesh boundaries in the solid 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...
MySolidTetgenMesh< SOLID_ELEMENT > * Solid_mesh_pt
Bulk solid mesh.
Vector< SolidMesh * > Solid_fsi_traction_mesh_pt
Meshes of FSI traction elements.
UnstructuredFSIProblem()
Constructor:
void create_lagrange_multiplier_elements()
Create elements that enforce prescribed boundary motion for the pseudo-solid fluid mesh by Lagrange m...
unsigned nfluid_inflow_traction_boundary()
Return total number of mesh boundaries that make up the inflow boundary.
Vector< unsigned > Inflow_boundary_id
IDs of fluid mesh boundaries along which inflow boundary conditions are applied.
Vector< unsigned > Pinned_solid_boundary_id
IDs of solid mesh boundaries where displacements are pinned.
FluidTetMesh< FLUID_ELEMENT > * Fluid_mesh_pt
Bulk fluid mesh.
Vector< unsigned > Fluid_fsi_boundary_id
IDs of fluid mesh boundaries which make up the FSI interface.
unsigned nfluid_fsi_boundary()
Return total number of mesh boundaries in the fluid mesh that make up the FSI interface.
void doc_solid_boundary_coordinates(const unsigned &i)
Sanity check: Doc boundary coordinates on i-th solid FSI interface.
void create_fsi_traction_elements()
Create FSI traction elements.
~UnstructuredFSIProblem()
Destructor (empty)
Vector< unsigned > Outflow_boundary_id
IDs of fluid mesh boundaries along which inflow boundary conditions are applied.
unsigned nfluid_outflow_traction_boundary()
Return total number of mesh boundaries that make up the outflow boundary.
void create_fluid_traction_elements()
Create fluid traction elements at inflow.
/////////////////////////////////////////////////////////////// /////////////////////////////////////...
double P_in
Fluid pressure on inflow boundary.
double Nu
Poisson's ratio for generalised Hookean constitutive equation.
double Q
Default FSI parameter.
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 Re
Default Reynolds number.
double P_out
Fluid pressure on outflow boundary.
ConstitutiveLaw * Constitutive_law_pt
Pointer to constitutive law.
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.
int main(int argc, char **argv)
Demonstrate how to solve an unstructured 3D FSI problem.