30 #ifndef OOMPH_FSI_HEADER 31 #define OOMPH_FSI_HEADER 35 #include <oomph-lib-config.h> 114 paired_pressure_data)=0;
233 Q_pt(&Default_Q_Value), Ignore_shear_stress_in_jacobian(false) {}
255 void setup_fsi_wall_element(
const unsigned& nlagr_solid,
256 const unsigned& ndim_fluid);
263 const double &
q()
const {
return *Q_pt;}
274 void enable_fluid_loading_on_both_sides();
286 {
return Only_front_is_loaded_by_fluid;}
303 Add_external_interaction_data=
true;
304 Ignore_shear_stress_in_jacobian=
false;
315 {Ignore_shear_stress_in_jacobian=
true; }
320 {Ignore_shear_stress_in_jacobian=
false; }
324 void node_update_adjacent_fluid_elements();
337 if(Solve_for_consistent_newmark_accel_flag)
339 fill_in_jacobian_for_newmark_accel(jacobian);
351 fill_in_jacobian_from_solid_position_by_fd(jacobian);
352 fill_in_jacobian_from_external_interaction_by_fd(full_residuals,jacobian);
360 if (!Ignore_shear_stress_in_jacobian)
362 node_update_adjacent_fluid_elements();
372 if (!Ignore_shear_stress_in_jacobian)
374 node_update_adjacent_fluid_elements();
382 if (!Ignore_shear_stress_in_jacobian)
384 node_update_adjacent_fluid_elements();
394 if (!Ignore_shear_stress_in_jacobian)
396 node_update_adjacent_fluid_elements();
404 if (!Ignore_shear_stress_in_jacobian)
406 node_update_adjacent_fluid_elements();
416 if (!Ignore_shear_stress_in_jacobian)
418 node_update_adjacent_fluid_elements();
425 if (!Ignore_shear_stress_in_jacobian)
427 node_update_adjacent_fluid_elements();
437 if (!Ignore_shear_stress_in_jacobian)
439 node_update_adjacent_fluid_elements();
447 if (!Ignore_shear_stress_in_jacobian)
449 node_update_adjacent_fluid_elements();
459 if (!Ignore_shear_stress_in_jacobian)
461 node_update_adjacent_fluid_elements();
469 if (!Ignore_shear_stress_in_jacobian)
471 node_update_adjacent_fluid_elements();
481 if (!Ignore_shear_stress_in_jacobian)
483 node_update_adjacent_fluid_elements();
511 void fluid_load_vector(
const unsigned& intpt,
522 void identify_all_field_data_for_external_interaction(
523 Vector<std::set<FiniteElement*> >
const &external_elements_pt,
524 std::set<std::pair<Data*,unsigned> > &paired_iteraction_data);
528 void identify_all_geometric_data_for_external_interaction(
529 Vector<std::set<FiniteElement*> >
const &external_elements_pt,
530 std::set<Data*> &external_geometric_data_pt);
569 namespace FSI_functions
611 template<
class FLUID_ELEMENT,
unsigned DIM_FLUID>
615 Mesh*
const &fluid_mesh_pt,
617 const unsigned& face=0)
621 <FLUID_ELEMENT, DIM_FLUID>(problem_pt,
622 boundary_in_fluid_mesh,
644 template<
class FLUID_ELEMENT,
unsigned DIM_FLUID>
647 const unsigned &boundary_in_fluid_mesh,
648 Mesh*
const &fluid_mesh_pt,
649 Mesh*
const &solid_mesh_pt,
650 const unsigned& face=0)
654 <FLUID_ELEMENT, DIM_FLUID>(problem_pt,
655 boundary_in_fluid_mesh,
681 template<
class SOLID_ELEMENT,
unsigned DIM_SOLID>
685 Mesh*
const &solid_mesh_pt,
690 <SOLID_ELEMENT, DIM_SOLID>(problem_pt,
693 lagrange_multiplier_mesh_pt,
713 template<
class SOLID_ELEMENT,
unsigned DIM_SOLID>
716 const unsigned & b_solid_fsi,
717 Mesh*
const &solid_mesh_pt,
718 Mesh*
const &lagrange_multiplier_mesh_pt)
723 <SOLID_ELEMENT, DIM_SOLID>(problem_pt,
726 lagrange_multiplier_mesh_pt,
756 std::ofstream some_file;
757 std::ostringstream filename;
774 filename << doc_info.
directory() <<
"/fsi_doc_fluid_mesh" 775 << doc_info.
number() <<
".dat";
776 some_file.open(filename.str().c_str());
777 fluid_mesh_pt->
output(some_file,npts);
787 std::map<Data*,Node*> solid_node_pt;
788 unsigned nnod=wall_mesh_pt->
nnode();
789 for (
unsigned j=0;j<nnod;j++)
800 std::map<Data*,FiniteElement*> internal_data_element_pt;
801 unsigned nelemf=fluid_mesh_pt->
nelement();
802 for (
unsigned e=0;
e<nelemf;
e++)
805 for (
unsigned k=0;k<ninternal;k++)
807 internal_data_element_pt[
817 for (std::set<int>::iterator it=procs.begin();
818 it!=procs.end();it++)
820 unsigned d=unsigned((*it));
822 for (
unsigned e=0;
e<n_ext_halo_f;
e++)
824 unsigned ninternal=fluid_mesh_pt->
825 external_halo_element_pt(d,
e)->ninternal_data();
826 for (
unsigned k=0;k<ninternal;k++)
828 internal_data_element_pt[
841 unsigned nelem=wall_mesh_pt->
nelement();
842 for (
unsigned e=0;
e<nelem;
e++)
848 <<
"/fsi_doc_wall_element" << doc_info.
number() <<
"-" 850 some_file.open(filename.str().c_str());
864 unsigned ndim_local = el_pt->
dim();
872 std::map<FiniteElement*,bool> element_internal_data_has_been_plotted;
877 some_file <<
"ZONE I=" << nint << std::endl;
878 for (
unsigned i=0;
i<nint;
i++)
880 for (
unsigned j=0;j<ndim_local;j++)
885 for (
unsigned j=0;j<ndim_eulerian;j++)
887 some_file << x[j] <<
" ";
889 some_file <<
i << std::endl;
899 unsigned n_loaded_face=2;
902 for (
unsigned face=0;face<n_loaded_face;face++)
904 some_file <<
"ZONE I=" << nint << std::endl;
905 for (
unsigned i=0;
i<nint;
i++)
916 for (
unsigned j=0;j<ndim_eulerian;j++)
918 some_file << x[j] <<
" ";
920 some_file <<
i << std::endl;
927 std::map<Data*,unsigned> data_count;
928 std::map<FiniteElement*,unsigned> internal_data_count;
932 unsigned nexternal_interaction_field =
933 external_interaction_field_data_pt.size();
934 for (
unsigned l=0;l<nexternal_interaction_field;l++)
936 data_count[external_interaction_field_data_pt[l]]++;
937 if (internal_data_element_pt[external_interaction_field_data_pt[l]]!=0)
939 internal_data_count[internal_data_element_pt[
940 external_interaction_field_data_pt[l]]]++;
948 unsigned nexternal_interaction_geom =
949 external_interaction_geometric_data_pt.size();
950 for (
unsigned l=0;l<nexternal_interaction_geom;l++)
952 data_count[external_interaction_geometric_data_pt[l]]++;
953 if (internal_data_element_pt[
954 external_interaction_geometric_data_pt[l]]!=0)
956 internal_data_count[internal_data_element_pt[
957 external_interaction_geometric_data_pt[l]]]++;
964 for(std::map<Data*,unsigned>::iterator it=data_count.begin();
965 it != data_count.end(); it++)
967 Data* unique_data_pt=it->first;
971 Node* node_pt=
dynamic_cast<Node*
>(unique_data_pt);
980 if (solid_node_pt[unique_data_pt]!=0)
982 some_file <<
"TEXT " ;
983 for (
unsigned j=0;j<ndim_eulerian;j++)
985 some_file << label[j] << solid_node_pt[unique_data_pt]->x(j)
989 some_file <<
"CS=GRID, HU=FRAME, H=2.5, AN=MIDCENTER, C=GREEN " 990 <<
"T=\"" << it->second <<
"\"" << std::endl;
995 else if (internal_data_element_pt[unique_data_pt]!=0)
997 if (!element_internal_data_has_been_plotted[
998 internal_data_element_pt[unique_data_pt]])
1000 some_file <<
"TEXT " ;
1002 FiniteElement* fluid_el_pt=internal_data_element_pt[unique_data_pt];
1010 for (
unsigned k=0;k<ndim_eulerian;k++)
1012 s_fluid[k]=0.5*(s_max+
s_min)+0.1*(s_max-s_min);
1015 for (
unsigned j=0;j<ndim_eulerian;j++)
1017 some_file << label[j] << x_fluid[j] <<
" ";
1020 some_file <<
"CS=GRID, HU=FRAME, H=2.5, AN=MIDCENTER, C=BLUE " 1021 <<
"T=\"" << it->second <<
"\"" 1026 element_internal_data_has_been_plotted[
1027 internal_data_element_pt[unique_data_pt]]=
true;
1033 std::ostringstream error_message;
1035 <<
"Data that affects the load on an FSIWallElement\n" 1036 <<
"is neither a (fluid) Node, nor a SolidNode nor\n" 1037 <<
"internal Data in a (fluid) element\n" 1038 <<
"I don't think this should happen..." 1041 OOMPH_CURRENT_FUNCTION,
1042 OOMPH_EXCEPTION_LOCATION);
1049 some_file <<
"TEXT " ;
1050 for (
unsigned j=0;j<ndim_eulerian;j++)
1052 some_file << label[j] << node_pt->
x(j) <<
", ";
1054 some_file <<
"CS=GRID, HU=FRAME, H=2.5, AN=MIDCENTER, C=RED "<<
"T=\"" 1055 << it->second <<
"\"" 1060 #ifdef OOMPH_HAS_MPI 1075 unsigned nnode_fluid=fluid_mesh_pt->
nnode();
1076 for (
unsigned j=0;j<nnode_fluid;j++)
1080 NODE* node_pt=
dynamic_cast<NODE*
>(fluid_mesh_pt->
node_pt(j));
1082 unsigned ndim_eulerian=node_pt->
ndim();
1087 <<
"/fsi_doc_fluid_element" 1088 << doc_info.
number() <<
"-" 1090 some_file.open(filename.str().c_str());
1091 some_file <<
"ZONE" << std::endl;
1092 for (
unsigned i=0;
i<ndim_eulerian;
i++)
1094 some_file << node_pt->x(
i) <<
" ";
1096 some_file << std::endl;
1104 std::map<Data*,unsigned> data_count;
1105 unsigned ngeom=geom_obj_pt.size();
1106 for (
unsigned i=0;
i<ngeom;
i++)
1108 unsigned ngeom_dat=geom_obj_pt[
i]->ngeom_data();
1109 for (
unsigned k=0;k<ngeom_dat;k++)
1111 data_count[geom_obj_pt[
i]->geom_data_pt(k)]++;
1116 bool written_something=
false;
1120 for(std::map<Data*,unsigned>::iterator it=data_count.begin();
1121 it != data_count.end(); it++)
1123 Data* unique_data_pt=it->first;
1126 if (solid_node_pt[unique_data_pt]!=0)
1128 some_file <<
"TEXT " ;
1129 for (
unsigned j=0;j<ndim_eulerian;j++)
1131 some_file << label[j] << solid_node_pt[unique_data_pt]->x(j)
1135 some_file <<
"CS=GRID, HU=FRAME, H=2.5, AN=MIDCENTER, C=GREEN "<<
"T=\"" 1136 << unique_data_pt->
nvalue() <<
"\"" 1140 written_something=
true;
1145 std::ostringstream warn_message;
1147 <<
"Info: Position of a fluid node is affected by Data that" 1148 <<
"is not a SolidNode --> Can't plot this Data. \n\n" 1149 <<
"(You may also want to check if this is exepcted or likely to\n" 1150 <<
"indicate a bug in your code...)" 1153 "FSI_functions::doc_fsi()",
1154 OOMPH_EXCEPTION_LOCATION);
1163 if (written_something) count++;
FSIWallElement(const FSIWallElement &)
Broken copy constructor.
virtual void get_residuals(Vector< double > &residuals)
Calculate the vector of residuals of the equations in the element. By default initialise the vector t...
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
void setup_bulk_elements_adjacent_to_face_mesh(Problem *problem_pt, Vector< unsigned > &boundary_in_bulk_mesh, Mesh *const &bulk_mesh_pt, Vector< Mesh *> &face_mesh_pt, const unsigned &interaction=0)
Identify the FaceElements (stored in the mesh pointed to by face_mesh_pt) that are adjacent to the bu...
Vector< Data * > external_interaction_geometric_data_pt() const
Return vector of pointers to the geometric Data objects that affect the interactions on the element...
virtual void fill_in_contribution_to_residuals(Vector< double > &residuals)
Add the elemental contribution to the residuals vector. Note that this function will NOT initialise t...
unsigned nexternal_halo_element()
Total number of external halo elements in this Mesh.
This is a base class for all SolidFiniteElements that participate in FSI computations. These elements provide interfaces and generic funcionality for the two additional roles that SolidFiniteElements play in FSI problems:They parameterise the domain boundary for the fluid domain. To allow them to play this role, FSIWallElements are derived from the SolidFiniteElement and the GeomObject class, indicating that the every specific FSIWallElement must implement the pure virtual function GeomObject::position(...) which should compute the position vector to a point in the SolidFiniteElement, parametrised by its local coordinates.In FSI problems fluid exerts a traction onto the wall and this traction must be added to any other load terms (such as an external pressure acting on an elastic pipe) that are already applied to the SolidFiniteElements by other means.
Vector< double > & external_element_local_coord(const unsigned &interaction_index, const unsigned &ipt)
Access function to get source element's local coords for specified interaction index at specified int...
bool only_front_is_loaded_by_fluid() const
Is the element exposed to (and hence loaded by) fluid only on its "front"? True by default...
void fill_in_jacobian_from_internal_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian, const bool &fd_all_data=false)
Calculate the contributions to the jacobian from the internal degrees of freedom using finite differe...
virtual void get_load(const Vector< double > &s, const Vector< double > &N, Vector< double > &load)=0
Compute the load vector that is applied by current element (at its local coordinate s) onto the adjac...
Information for documentation of results: Directory and file number to enable output in the form RESL...
void reset_after_external_interaction_geometric_fd()
Function that is call after the finite differencing of the external interaction data associated with ...
std::string directory() const
Output directory.
GeneralisedElement *& external_halo_element_pt(const unsigned &p, const unsigned &e)
Access fct to the e-th external halo element in this Mesh whose non-halo counterpart is held on proce...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
double * Q_pt
Pointer to the ratio, , of the stress used to non-dimensionalise the fluid stresses to the stress us...
virtual void describe_local_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the local dofs of the element[s]. The ostream specifies the output stream to whi...
void disable_shear_stress_in_jacobian()
Call this function to ignore shear stress component of load when calculating the Jacobian, i.e. to ignore fluid velocity Data in the FSIFluidElement and "far away" geometric Data that affects nodal positions in the FSIFluidElement, also to bypass node updates in the FSIFluidElement. This functionality is provided to allow the user to deem the coupling to the shear stress component of the fluid equations to be irrelevant.
A general Finite Element class.
void include_external_load_data()
Include all external fluid data that affects the load in the computation of the element's Jacobian ma...
bool is_halo() const
Is this element a halo?
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
void apply_no_slip_on_moving_wall(Node *node_pt)
Apply no-slip condition for N.St. on a moving wall node, u = St dR/dt, where the Strouhal number St =...
virtual void identify_pressure_data(std::set< std::pair< Data *, unsigned > > &paired_pressure_data)=0
Add to the set paired_pressure_data pairs containing.
virtual void identify_load_data(std::set< std::pair< Data *, unsigned > > &paired_load_data)=0
Add to the set paired_load_data pairs containing.
Vector< Data * > external_interaction_field_data_pt() const
Return vector of pointers to the field Data objects that affect the interactions on the element...
void fill_in_jacobian_from_external_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian, const bool &fd_all_data=false)
Calculate the contributions to the jacobian from the external degrees of freedom using finite differe...
unsigned & number()
Number used (e.g.) for labeling output files.
unsigned long nelement() const
Return number of elements in the mesh.
void operator=(const FSIWallElement &)
Broken assignment operator.
virtual double s_min() const
Min value of local coordinate.
void output(std::ostream &outfile)
Output for all elements.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
void reset_after_external_fd()
Function that is call after the finite differencing of the external data. This may be overloaded to r...
SolidNode * node_pt(const unsigned long &n)
Return a pointer to the n-th global SolidNode.
unsigned ndof() const
Return the number of equations/dofs in the element.
unsigned nodal_dimension() const
Return the required Eulerian dimension of the nodes in this element.
void operator=(const FSIFluidElement &)
Broken assignment operator.
double & x(const unsigned &i)
Return the i-th nodal coordinate.
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
void reset_in_external_interaction_field_fd(const unsigned &i)
Function called within the finite difference loop for external interaction data after the values in t...
void enable_shear_stress_in_jacobian()
void update_in_external_fd(const unsigned &i)
After an external data change, update the nodal positions.
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
bool Only_front_is_loaded_by_fluid
Is the element exposed to (and hence loaded by) fluid only on its "front"? True by default...
void reset_in_internal_fd(const unsigned &i)
Function called within the finite difference loop for internal data after the values in the i-th exte...
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
void reset_in_external_interaction_geometric_fd(const unsigned &i)
Function called within the finite difference loop for external interaction data after the values in t...
FSIFluidElement()
Constructor.
void reset_after_solid_position_fd()
Function that is call after the finite differencing of the solid position data. This may be overloade...
void exclude_external_load_data()
Do not include any external data that affects the load in the computation of element's Jacobian matri...
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
void update_in_solid_position_fd(const unsigned &i)
After an internal data change, update the nodal positions.
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
void update_in_external_interaction_geometric_fd(const unsigned &i)
After an external geometric data change, update the nodal positions.
void reset_after_internal_fd()
Function that is call after the finite differencing of the internal data. This may be overloaded to r...
A class that represents a collection of data; each Data object may contain many different individual ...
Data *const & variable_position_pt() const
Pointer to variable_position data (const version)
bool Ignore_shear_stress_in_jacobian
Set this flag to true to ignore shear stress component of load when calculating the Jacobian...
void update_in_nodal_fd(const unsigned &i)
After a nodal data change, update the nodal positions.
virtual ~FSIWallElement()
Empty virtual destructor for safety.
virtual double s_max() const
Max. value of local coordinate.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
double *& q_pt()
Return a pointer the ratio of stress scales used to non-dimensionalise the fluid and solid equations...
void reset_in_solid_position_fd(const unsigned &i)
Function called within the finite difference loop for solid position data after the values in the i-t...
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
unsigned long nnode() const
Return number of nodes in the mesh.
void update_in_external_interaction_field_fd(const unsigned &i)
After an external field data change, update the nodal positions.
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
FSIWallElement()
Constructor. Note that element is not fully-functional until its setup_fsi_wall_element() function ha...
virtual void fill_in_jacobian_from_nodal_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the contributions to the jacobian from the nodal degrees of freedom using finite difference...
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
unsigned ninternal_data() const
Return the number of internal data objects.
void setup_fluid_load_info_for_solid_elements(Problem *problem_pt, const unsigned &boundary_in_fluid_mesh, Mesh *const &fluid_mesh_pt, Mesh *const &solid_mesh_pt, const unsigned &face=0)
Set up the information that the FSIWallElements in the specified solid mesh require to obtain the flu...
void broken_assign(const std::string &class_name)
Issue error message and terminate execution.
void reset_in_external_fd(const unsigned &i)
Function called within the finite difference loop for external data after the values in the i-th exte...
const double & q() const
Return the ratio of the stress scales used to non-dimensionalise the fluid and solid equations...
void reset_in_nodal_fd(const unsigned &i)
Function called within the finite difference loop for nodal data after the i-th nodal values is reset...
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
FiniteElement *& external_element_pt(const unsigned &interaction_index, const unsigned &ipt)
Access function to source element for specified interaction index at specified integration point...
void reset_after_nodal_fd()
Function that is call after the finite differencing of the nodal data. This may be overloaded to rese...
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
void update_in_internal_fd(const unsigned &i)
After an internal data change, update the nodal positions.
static bool Dont_warn_about_missing_adjacent_fluid_elements
Static flag that allows the suppression of warning messages.
FSIFluidElement(const FSIFluidElement &)
Broken copy constructor.
double Strouhal_for_no_slip
Strouhal number St = a/(UT) for application of no slip condition. Initialised to 1.0.
void setup_solid_elements_for_displacement_bc(Problem *problem_pt, const unsigned &b_solid_fsi, Mesh *const &solid_mesh_pt, Mesh *const &lagrange_multiplier_mesh_pt)
Setup multi-domain interaction required for imposition of solid displacements onto the pseudo-solid f...
void reset_after_external_interaction_field_fd()
Function that is call after the finite differencing of the external interaction data associated with ...
std::set< int > external_halo_proc()
Return the set of processors that hold external halo nodes. This is required to avoid having to pass ...
static double Default_Q_Value
Static default value for the ratio of stress scales used in the fluid and solid equations (default is...
SolidFiniteElement class.
void doc_fsi(Mesh *fluid_mesh_pt, SolidMesh *wall_mesh_pt, DocInfo &doc_info)
The FSIFluidElement class is a base class for all fluid finite elements that apply a load (traction) ...