30 #include "navier_stokes.h"
32 #include "constitutive.h"
35 #include "meshes/triangle_mesh.h"
38 using namespace oomph;
56 const Vector<double> &xi,
75 dynamic_cast<BoundaryNodeBase*
>(nod_pt)!=0)&&
78 ( (nod_pt->x(0)>1.6)&&(nod_pt->x(0)<4.75)&&
80 (nod_pt->x(1)>0.1125)&&(nod_pt->x(1)<2.8) ) ||
82 ( (nod_pt->x(1)<0.3)&&
84 ( ( (nod_pt->x(0)>3.0)&&(nod_pt->x(0)<3.1) ) ||
85 ( (nod_pt->x(0)<4.6)&&(nod_pt->x(0)>4.5) ) )
111 template<
class ELEMENT>
113 public virtual SolidMesh
120 const std::string& element_file_name,
121 const std::string& poly_file_name,
122 TimeStepper* time_stepper_pt=
123 &Mesh::Default_TimeStepper) :
124 TriangleMesh<ELEMENT>(node_file_name,element_file_name,
125 poly_file_name, time_stepper_pt)
128 set_lagrangian_nodal_coordinates();
133 unsigned n_node=this->nnode();
134 for (
unsigned j=0;j<n_node;j++)
136 Node* nod_pt=this->node_pt(j);
139 if (nod_pt->x(1)<0.15)
141 this->remove_boundary_node(0,nod_pt);
142 this->add_boundary_node(1,nod_pt);
148 this->remove_boundary_node(0,nod_pt);
149 this->add_boundary_node(2,nod_pt);
154 TriangleMesh<ELEMENT>::setup_boundary_element_info();
157 this->
template setup_boundary_coordinates<ELEMENT>(1);
158 this->
template setup_boundary_coordinates<ELEMENT>(2);
177 template<
class ELEMENT>
179 public virtual SolidMesh
186 const std::string& element_file_name,
187 const std::string& poly_file_name,
188 TimeStepper* time_stepper_pt=
189 &Mesh::Default_TimeStepper) :
190 TriangleMesh<ELEMENT>(node_file_name,element_file_name,
191 poly_file_name, time_stepper_pt)
194 set_lagrangian_nodal_coordinates();
197 this->set_nboundary(4);
199 unsigned n_node=this->nnode();
200 for (
unsigned j=0;j<n_node;j++)
202 Node* nod_pt=this->node_pt(j);
205 if (nod_pt->x(0)<0.226)
207 this->remove_boundary_node(0,nod_pt);
208 this->add_boundary_node(1,nod_pt);
211 if (nod_pt->x(1)<0.2) this->add_boundary_node(0,nod_pt);
212 if (nod_pt->x(1)>4.06) this->add_boundary_node(0,nod_pt);
216 if (nod_pt->x(0)>8.28)
218 this->remove_boundary_node(0,nod_pt);
219 this->add_boundary_node(2,nod_pt);
222 if (nod_pt->x(1)<0.2) this->add_boundary_node(0,nod_pt);
223 if (nod_pt->x(1)>4.06) this->add_boundary_node(0,nod_pt);
230 this->remove_boundary_node(0,nod_pt);
231 this->add_boundary_node(3,nod_pt);
234 if (nod_pt->x(1)<0.2) this->add_boundary_node(0,nod_pt);
237 TriangleMesh<ELEMENT>::setup_boundary_element_info();
246 ofstream some_file(
"RESLT/boundary_generation_test.dat");
249 this->
template setup_boundary_coordinates<ELEMENT>(1);
250 this->
template setup_boundary_coordinates<ELEMENT>(2);
251 this->
template setup_boundary_coordinates<ELEMENT>(3,some_file);
272 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
287 return Fluid_mesh_pt;
293 return Solid_mesh_pt;
297 void doc_solution(DocInfo& doc_info);
302 void create_fsi_traction_elements();
306 void create_lagrange_multiplier_elements();
309 void doc_solid_boundary_coordinates();
334 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
342 string fluid_node_file_name=
"fluid.fig.1.node";
343 string fluid_element_file_name=
"fluid.fig.1.ele";
344 string fluid_poly_file_name=
"fluid.fig.1.poly";
346 fluid_element_file_name,
347 fluid_poly_file_name);
350 std::ofstream pseudo_solid_bc_file(
"pinned_pseudo_solid_nodes.dat");
355 unsigned nbound=Fluid_mesh_pt->nboundary();
356 for(
unsigned ibound=0;ibound<nbound;ibound++)
358 unsigned num_nod=Fluid_mesh_pt->nboundary_node(ibound);
359 for (
unsigned inod=0;inod<num_nod;inod++)
365 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->pin(0);
367 Fluid_mesh_pt->boundary_node_pt(ibound,inod)->pin(1);
371 if ((ibound==0)||(ibound==1)||(ibound==2))
373 for(
unsigned i=0;i<2;i++)
376 SolidNode* nod_pt=Fluid_mesh_pt->boundary_node_pt(ibound,inod);
377 nod_pt->pin_position(i);
380 pseudo_solid_bc_file << nod_pt->x(i) <<
" ";
382 pseudo_solid_bc_file << std::endl;
388 pseudo_solid_bc_file.close();
392 unsigned n_element = Fluid_mesh_pt->nelement();
393 for(
unsigned e=0;e<n_element;e++)
396 FLUID_ELEMENT* el_pt =
397 dynamic_cast<FLUID_ELEMENT*
>(Fluid_mesh_pt->element_pt(e));
403 el_pt->constitutive_law_pt() =
414 double y_min=fluid_mesh_pt()->boundary_node_pt(ibound,0)->x(1);;
418 unsigned num_nod= fluid_mesh_pt()->nboundary_node(ibound);
419 for (
unsigned inod=1;inod<num_nod;inod++)
421 double y=fluid_mesh_pt()->boundary_node_pt(ibound,inod)->x(1);
431 double y_mid=0.5*(y_min+y_max);
434 const unsigned n_boundary = fluid_mesh_pt()->nboundary();
435 for (
unsigned ibound=0;ibound<n_boundary;ibound++)
437 const unsigned num_nod= fluid_mesh_pt()->nboundary_node(ibound);
438 for (
unsigned inod=0;inod<num_nod;inod++)
443 double y=fluid_mesh_pt()->boundary_node_pt(ibound,inod)->x(1);
444 double veloc=1.5/(y_max-y_min)*
445 (y-y_min)*(y_max-y)/((y_mid-y_min)*(y_max-y_mid));
446 fluid_mesh_pt()->boundary_node_pt(ibound,inod)->set_value(0,veloc);
447 fluid_mesh_pt()->boundary_node_pt(ibound,inod)->set_value(1,0.0);
452 fluid_mesh_pt()->boundary_node_pt(ibound,inod)->set_value(0,0.0);
453 fluid_mesh_pt()->boundary_node_pt(ibound,inod)->set_value(1,0.0);
463 string solid_node_file_name=
"solid.fig.1.node";
464 string solid_element_file_name=
"solid.fig.1.ele";
465 string solid_poly_file_name=
"solid.fig.1.poly";
467 solid_element_file_name,
468 solid_poly_file_name);
472 n_element = Solid_mesh_pt->nelement();
473 for(
unsigned i=0;i<n_element;i++)
476 SOLID_ELEMENT *el_pt =
477 dynamic_cast<SOLID_ELEMENT*
>(Solid_mesh_pt->element_pt(i));
480 el_pt->constitutive_law_pt() =
489 num_nod=Solid_mesh_pt->nboundary_node(ibound);
490 for (
unsigned inod=0;inod<num_nod;inod++)
492 Solid_mesh_pt->boundary_node_pt(ibound,inod)->pin_position(0);
493 Solid_mesh_pt->boundary_node_pt(ibound,inod)->pin_position(1);
501 Traction_mesh_pt=
new SolidMesh;
504 create_fsi_traction_elements();
511 Lagrange_multiplier_mesh_pt=
new SolidMesh;
512 create_lagrange_multiplier_elements();
519 add_sub_mesh(Fluid_mesh_pt);
520 add_sub_mesh(Solid_mesh_pt);
521 add_sub_mesh(Traction_mesh_pt);
522 add_sub_mesh(Lagrange_multiplier_mesh_pt);
534 Multi_domain_functions::Doc_boundary_coordinate_file.open(
535 "fluid_boundary_test.dat");
541 FSI_functions::setup_fluid_load_info_for_solid_elements<FLUID_ELEMENT,2>
542 (
this,3,Fluid_mesh_pt,Traction_mesh_pt);
545 Multi_domain_functions::Doc_boundary_coordinate_file.close();
548 doc_solid_boundary_coordinates();
551 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
561 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
567 std::ofstream the_file(
"solid_boundary_test.dat");
570 double zeta_min= 1.0e40;
571 double zeta_max=-1.0e40;
574 unsigned n_face_element = Traction_mesh_pt->nelement();
575 for(
unsigned e=0;e<n_face_element;e++)
578 FSISolidTractionElement<SOLID_ELEMENT,2>* el_pt=
579 dynamic_cast<FSISolidTractionElement<SOLID_ELEMENT,2>*
>
580 (Traction_mesh_pt->element_pt(e));
584 Vector<double> zeta(1);
587 the_file << el_pt->tecplot_zone_string(n_plot);
590 unsigned num_plot_points=el_pt->nplot_points(n_plot);
591 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
594 el_pt->get_s_plot(iplot,n_plot,s);
595 el_pt->interpolated_zeta(s,zeta);
596 el_pt->interpolated_x(s,x);
597 for (
unsigned i=0;i<2;i++)
599 the_file << x[i] <<
" ";
601 the_file << zeta[0] <<
" ";
604 if (zeta[0]<zeta_min) zeta_min=zeta[0];
605 if (zeta[0]>zeta_max) zeta_max=zeta[0];
607 the_file << std::endl;
616 the_file.open(
"fsi_geom_object.dat");
617 unsigned nplot=10000;
618 Vector<double> zeta(1);
620 for (
unsigned i=0;i<nplot;i++)
622 zeta[0]=zeta_min+(zeta_max-zeta_min)*
double(i)/double(nplot-1);
623 Solid_fsi_boundary_pt->position(zeta,r);
624 the_file << r[0] <<
" " << r[1] << std::endl;
636 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
644 unsigned n_element = solid_mesh_pt()->nboundary_element(b);
647 for(
unsigned e=0;e<n_element;e++)
650 SOLID_ELEMENT* bulk_elem_pt =
dynamic_cast<SOLID_ELEMENT*
>(
651 solid_mesh_pt()->boundary_element_pt(b,e));
654 int face_index = solid_mesh_pt()->face_index_at_boundary(b,e);
657 FSISolidTractionElement<SOLID_ELEMENT,2>* el_pt=
658 new FSISolidTractionElement<SOLID_ELEMENT,2>(bulk_elem_pt,face_index);
661 Traction_mesh_pt->add_element_pt(el_pt);
664 el_pt->set_boundary_number_in_bulk_mesh(b);
678 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
684 Solid_fsi_boundary_pt=
692 unsigned n_element = Fluid_mesh_pt->nboundary_element(b);
695 for(
unsigned e=0;e<n_element;e++)
698 FLUID_ELEMENT* bulk_elem_pt =
dynamic_cast<FLUID_ELEMENT*
>(
699 Fluid_mesh_pt->boundary_element_pt(b,e));
702 int face_index = Fluid_mesh_pt->face_index_at_boundary(b,e);
705 ImposeDisplacementByLagrangeMultiplierElement<FLUID_ELEMENT>* el_pt =
706 new ImposeDisplacementByLagrangeMultiplierElement<FLUID_ELEMENT>(
707 bulk_elem_pt,face_index);
710 Lagrange_multiplier_mesh_pt->add_element_pt(el_pt);
715 el_pt->set_boundary_shape_geom_object_pt(Solid_fsi_boundary_pt,b);
718 unsigned nnod=el_pt->nnode();
719 for (
unsigned j=0;j<nnod;j++)
721 Node* nod_pt = el_pt->node_pt(j);
724 if (nod_pt->is_on_boundary(0))
728 unsigned n_bulk_value=el_pt->nbulk_value(j);
731 unsigned nval=nod_pt->nvalue();
732 for (
unsigned j=n_bulk_value;j<nval;j++)
746 template<
class FLUID_ELEMENT,
class SOLID_ELEMENT>
758 sprintf(filename,
"%s/fluid_soln%i.dat",doc_info.directory().c_str(),
760 some_file.open(filename);
761 Fluid_mesh_pt->output(some_file,npts);
766 sprintf(filename,
"%s/solid_soln%i.dat",doc_info.directory().c_str(),
768 some_file.open(filename);
769 Solid_mesh_pt->output(some_file,npts);
792 doc_info.set_directory(
"RESLT");
800 PseudoSolidNodeUpdateElement<TTaylorHoodElement<2>, TPVDElement<2,3> >,
801 TPVDElement<2,3> > problem;
804 problem.
fluid_mesh_pt()->output_boundaries(
"RESLT/fluid_boundaries.dat");
805 problem.solid_mesh_pt()->output_boundaries(
"RESLT/solid_boundaries.dat");
808 problem.doc_solution(doc_info);
813 double q_increment=1.0e-6;
816 problem.newton_solve();
819 problem.doc_solution(doc_info);
827 for (
unsigned i=0;i<nstep;i++)
830 problem.newton_solve();
833 problem.doc_solution(doc_info);
//////////////////////////////////////////////////////////////////////// ////////////////////////////...
FluidTriangleMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &poly_file_name, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor.
virtual ~FluidTriangleMesh()
Empty Destructor.
///////////////////////////////////////////////////////////////////// ///////////////////////////////...
MySolidTriangleMesh(const std::string &node_file_name, const std::string &element_file_name, const std::string &poly_file_name, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
Constructor:
virtual ~MySolidTriangleMesh()
Empty Destructor.
//////////////////////////////////////////////////////////////////////// ////////////////////////////...
void doc_solution(DocInfo &doc_info)
Doc the solution.
FluidTriangleMesh< FLUID_ELEMENT > * Fluid_mesh_pt
Fluid mesh.
UnstructuredFSIProblem()
Constructor.
void doc_solid_boundary_coordinates()
Sanity check: Doc boundary coordinates from solid side.
void create_lagrange_multiplier_elements()
Create elements that enforce prescribed boundary motion for the pseudo-solid fluid mesh by Lagrange m...
void create_fsi_traction_elements()
Create FSI traction elements.
~UnstructuredFSIProblem()
Destructor (empty)
MeshAsGeomObject * Solid_fsi_boundary_pt
GeomObject incarnation of fsi boundary in solid mesh.
SolidMesh * Lagrange_multiplier_mesh_pt
Pointers to mesh of Lagrange multiplier elements.
SolidMesh * Traction_mesh_pt
Vector of pointers to mesh of FSI traction elements.
MySolidTriangleMesh< SOLID_ELEMENT > *& solid_mesh_pt()
Access function for the solid mesh.
MySolidTriangleMesh< SOLID_ELEMENT > * Solid_mesh_pt
Solid mesh.
FluidTriangleMesh< FLUID_ELEMENT > *& fluid_mesh_pt()
Access function for the fluid mesh.
Namespace for physical parameters.
void gravity(const double &time, const Vector< double > &xi, Vector< double > &b)
Non-dimensional gravity as body force.
double Nu
Pseudo-solid Poisson ratio.
double Gravity
Non-dim gravity.
bool is_on_fsi_boundary(Node *nod_pt)
Boolean to identify if node is on fsi boundary.
double Re
Reynolds number.
ConstitutiveLaw * Constitutive_law_pt
Constitutive law for the solid (and pseudo-solid) mechanics.
int main()
///////////////////////////////////////////////////////////////////// ///////////////////////////////...