26#ifndef OOMPH_FSI_HEADER
27#define OOMPH_FSI_HEADER
31#include <oomph-lib-config.h>
91 std::set<std::pair<Data*, unsigned>>& paired_load_data) = 0;
101 std::set<std::pair<Data*, unsigned>>& paired_pressure_data) = 0;
234 const unsigned& ndim_fluid);
241 const double&
q()
const
517 Vector<std::set<FiniteElement*>>
const& external_elements_pt,
518 std::set<std::pair<Data*, unsigned>>& paired_iteraction_data);
523 Vector<std::set<FiniteElement*>>
const& external_elements_pt,
524 std::set<Data*>& external_geometric_data_pt);
559 namespace FSI_functions
600 template<
class FLUID_ELEMENT,
unsigned DIM_FLUID>
604 Mesh*
const& fluid_mesh_pt,
606 const unsigned& face = 0)
612 problem_pt, boundary_in_fluid_mesh, fluid_mesh_pt, solid_mesh_pt, face);
631 template<
class FLUID_ELEMENT,
unsigned DIM_FLUID>
634 const unsigned& boundary_in_fluid_mesh,
635 Mesh*
const& fluid_mesh_pt,
636 Mesh*
const& solid_mesh_pt,
637 const unsigned& face = 0)
643 problem_pt, boundary_in_fluid_mesh, fluid_mesh_pt, solid_mesh_pt, face);
664 template<
class SOLID_ELEMENT,
unsigned DIM_SOLID>
668 Mesh*
const& solid_mesh_pt,
675 problem_pt, b_solid_fsi, solid_mesh_pt, lagrange_multiplier_mesh_pt, 0);
691 template<
class SOLID_ELEMENT,
unsigned DIM_SOLID>
694 const unsigned& b_solid_fsi,
695 Mesh*
const& solid_mesh_pt,
696 Mesh*
const& lagrange_multiplier_mesh_pt)
702 problem_pt, b_solid_fsi, solid_mesh_pt, lagrange_multiplier_mesh_pt, 0);
728 std::ofstream some_file;
729 std::ostringstream filename;
746 filename << doc_info.
directory() <<
"/fsi_doc_fluid_mesh"
747 << doc_info.
number() <<
".dat";
748 some_file.open(filename.str().c_str());
749 fluid_mesh_pt->
output(some_file, npts);
757 std::map<Data*, Node*> solid_node_pt;
758 unsigned nnod = wall_mesh_pt->
nnode();
759 for (
unsigned j = 0; j < nnod; j++)
771 std::map<Data*, FiniteElement*> internal_data_element_pt;
772 unsigned nelemf = fluid_mesh_pt->
nelement();
773 for (
unsigned e = 0;
e < nelemf;
e++)
776 for (
unsigned k = 0; k < ninternal; k++)
778 internal_data_element_pt[fluid_mesh_pt->
element_pt(
e)
788 for (std::set<int>::iterator it = procs.begin(); it != procs.end(); it++)
790 unsigned d = unsigned((*it));
792 for (
unsigned e = 0;
e < n_ext_halo_f;
e++)
796 for (
unsigned k = 0; k < ninternal; k++)
798 internal_data_element_pt[fluid_mesh_pt
811 unsigned nelem = wall_mesh_pt->
nelement();
812 for (
unsigned e = 0;
e < nelem;
e++)
817 filename << doc_info.
directory() <<
"/fsi_doc_wall_element"
818 << doc_info.
number() <<
"-" <<
e <<
".dat";
819 some_file.open(filename.str().c_str());
833 unsigned ndim_local = el_pt->
dim();
841 std::map<FiniteElement*, bool> element_internal_data_has_been_plotted;
846 some_file <<
"ZONE I=" << nint << std::endl;
847 for (
unsigned i = 0;
i < nint;
i++)
849 for (
unsigned j = 0; j < ndim_local; j++)
854 for (
unsigned j = 0; j < ndim_eulerian; j++)
856 some_file << x[j] <<
" ";
858 some_file <<
i << std::endl;
869 unsigned n_loaded_face = 2;
872 for (
unsigned face = 0; face < n_loaded_face; face++)
874 some_file <<
"ZONE I=" << nint << std::endl;
875 for (
unsigned i = 0;
i < nint;
i++)
887 for (
unsigned j = 0; j < ndim_eulerian; j++)
889 some_file << x[j] <<
" ";
891 some_file <<
i << std::endl;
899 std::map<Data*, unsigned> data_count;
900 std::map<FiniteElement*, unsigned> internal_data_count;
904 unsigned nexternal_interaction_field =
905 external_interaction_field_data_pt.size();
906 for (
unsigned l = 0; l < nexternal_interaction_field; l++)
908 data_count[external_interaction_field_data_pt[l]]++;
909 if (internal_data_element_pt
910 [external_interaction_field_data_pt[l]] != 0)
913 [internal_data_element_pt
914 [external_interaction_field_data_pt[l]]]++;
922 unsigned nexternal_interaction_geom =
923 external_interaction_geometric_data_pt.size();
924 for (
unsigned l = 0; l < nexternal_interaction_geom; l++)
926 data_count[external_interaction_geometric_data_pt[l]]++;
927 if (internal_data_element_pt
928 [external_interaction_geometric_data_pt[l]] != 0)
931 [internal_data_element_pt
932 [external_interaction_geometric_data_pt[l]]]++;
939 for (std::map<Data*, unsigned>::iterator it = data_count.begin();
940 it != data_count.end();
943 Data* unique_data_pt = it->first;
947 Node* node_pt =
dynamic_cast<Node*
>(unique_data_pt);
956 if (solid_node_pt[unique_data_pt] != 0)
958 some_file <<
"TEXT ";
959 for (
unsigned j = 0; j < ndim_eulerian; j++)
961 some_file << label[j] << solid_node_pt[unique_data_pt]->x(j)
965 some_file <<
"CS=GRID, HU=FRAME, H=2.5, AN=MIDCENTER, C=GREEN "
966 <<
"T=\"" << it->second <<
"\"" << std::endl;
971 else if (internal_data_element_pt[unique_data_pt] != 0)
973 if (!element_internal_data_has_been_plotted
974 [internal_data_element_pt[unique_data_pt]])
976 some_file <<
"TEXT ";
979 internal_data_element_pt[unique_data_pt];
983 double s_max = fluid_el_pt->
s_max();
984 double s_min = fluid_el_pt->
s_min();
987 for (
unsigned k = 0; k < ndim_eulerian; k++)
989 s_fluid[k] = 0.5 * (s_max + s_min) + 0.1 * (s_max - s_min);
992 for (
unsigned j = 0; j < ndim_eulerian; j++)
994 some_file << label[j] << x_fluid[j] <<
" ";
997 some_file <<
"CS=GRID, HU=FRAME, H=2.5, AN=MIDCENTER, C=BLUE "
998 <<
"T=\"" << it->second
1004 element_internal_data_has_been_plotted
1005 [internal_data_element_pt[unique_data_pt]] =
true;
1010 std::ostringstream error_message;
1012 <<
"Data that affects the load on an FSIWallElement\n"
1013 <<
"is neither a (fluid) Node, nor a SolidNode nor\n"
1014 <<
"internal Data in a (fluid) element\n"
1015 <<
"I don't think this should happen..." << std::endl;
1017 OOMPH_CURRENT_FUNCTION,
1018 OOMPH_EXCEPTION_LOCATION);
1025 some_file <<
"TEXT ";
1026 for (
unsigned j = 0; j < ndim_eulerian; j++)
1028 some_file << label[j] << node_pt->
x(j) <<
", ";
1030 some_file <<
"CS=GRID, HU=FRAME, H=2.5, AN=MIDCENTER, C=RED "
1031 <<
"T=\"" << it->second <<
"\"" << std::endl;
1050 unsigned nnode_fluid = fluid_mesh_pt->
nnode();
1051 for (
unsigned j = 0; j < nnode_fluid; j++)
1054 NODE* node_pt =
dynamic_cast<NODE*
>(fluid_mesh_pt->
node_pt(j));
1056 unsigned ndim_eulerian = node_pt->
ndim();
1060 filename << doc_info.
directory() <<
"/fsi_doc_fluid_element"
1061 << doc_info.
number() <<
"-" << count <<
".dat";
1062 some_file.open(filename.str().c_str());
1063 some_file <<
"ZONE" << std::endl;
1064 for (
unsigned i = 0;
i < ndim_eulerian;
i++)
1066 some_file << node_pt->x(
i) <<
" ";
1068 some_file << std::endl;
1076 std::map<Data*, unsigned> data_count;
1077 unsigned ngeom = geom_obj_pt.size();
1078 for (
unsigned i = 0;
i < ngeom;
i++)
1080 unsigned ngeom_dat = geom_obj_pt[
i]->ngeom_data();
1081 for (
unsigned k = 0; k < ngeom_dat; k++)
1083 data_count[geom_obj_pt[
i]->geom_data_pt(k)]++;
1088 bool written_something =
false;
1092 for (std::map<Data*, unsigned>::iterator it = data_count.begin();
1093 it != data_count.end();
1096 Data* unique_data_pt = it->first;
1099 if (solid_node_pt[unique_data_pt] != 0)
1101 some_file <<
"TEXT ";
1102 for (
unsigned j = 0; j < ndim_eulerian; j++)
1104 some_file << label[j] << solid_node_pt[unique_data_pt]->x(j)
1108 some_file <<
"CS=GRID, HU=FRAME, H=2.5, AN=MIDCENTER, C=GREEN "
1109 <<
"T=\"" << unique_data_pt->
nvalue() <<
"\""
1113 written_something =
true;
1118 std::ostringstream warn_message;
1120 <<
"Info: Position of a fluid node is affected by Data that"
1121 <<
"is not a SolidNode --> Can't plot this Data. \n\n"
1122 <<
"(You may also want to check if this is exepcted or likely "
1124 <<
"indicate a bug in your code...)" << std::endl;
1126 "FSI_functions::doc_fsi()",
1127 OOMPH_EXCEPTION_LOCATION);
1136 if (written_something) count++;
A class that represents a collection of data; each Data object may contain many different individual ...
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
Information for documentation of results: Directory and file number to enable output in the form RESL...
std::string directory() const
Output directory.
unsigned & number()
Number used (e.g.) for labeling output files.
This is a base class for all elements that require external sources (e.g. FSI, multi-domain problems ...
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...
Vector< Data * > external_interaction_geometric_data_pt() const
Return vector of pointers to the geometric Data objects that affect the interactions on the element.
void fill_in_jacobian_from_external_interaction_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the contributions to the jacobian from all external interaction degrees of freedom (geometr...
FiniteElement *& external_element_pt(const unsigned &interaction_index, const unsigned &ipt)
Access function to source element for specified interaction index at specified integration point.
bool Add_external_interaction_data
Boolean flag to indicate whether to include the external data.
Vector< Data * > external_interaction_field_data_pt() const
Return vector of pointers to the field Data objects that affect the interactions on the element.
/////////////////////////////////////////////////////////////////////////
virtual void identify_load_data(std::set< std::pair< Data *, unsigned > > &paired_load_data)=0
Add to the set paired_load_data pairs containing.
void operator=(const FSIFluidElement &)=delete
Broken assignment operator.
FSIFluidElement()
Constructor.
FSIFluidElement(const FSIFluidElement &)=delete
Broken copy constructor.
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...
virtual void identify_pressure_data(std::set< std::pair< Data *, unsigned > > &paired_pressure_data)=0
Add to the set paired_pressure_data pairs containing.
////////////////////////////////////////////////////////////////////////// //////////////////////////...
void enable_fluid_loading_on_both_sides()
Allow element to be loaded by fluid on both sides. (Resizes containers for lookup schemes and initial...
void identify_all_field_data_for_external_interaction(Vector< std::set< FiniteElement * > > const &external_elements_pt, std::set< std::pair< Data *, unsigned > > &paired_iteraction_data)
Overload the function that must return all field data involved in the interactions from the external ...
FSIWallElement(const FSIWallElement &)=delete
Broken copy constructor.
void reset_after_nodal_fd()
Function that is call after the finite differencing of the nodal data. This may be overloaded to rese...
void identify_all_geometric_data_for_external_interaction(Vector< std::set< FiniteElement * > > const &external_elements_pt, std::set< Data * > &external_geometric_data_pt)
Function that must return all geometric data involved in the desired interactions from the external e...
void reset_after_external_fd()
Function that is call after the finite differencing of the external data. This may be overloaded to r...
void setup_fsi_wall_element(const unsigned &nlagr_solid, const unsigned &ndim_fluid)
Setup: Assign storage – pass the Eulerian dimension of the "adjacent" fluid elements and the number o...
void update_in_external_interaction_geometric_fd(const unsigned &i)
After an external geometric data change, update the nodal positions.
virtual ~FSIWallElement()
Empty virtual destructor for safety.
void fluid_load_vector(const unsigned &intpt, const Vector< double > &N, Vector< double > &load)
Get FE Jacobian by systematic finite differencing w.r.t. nodal positition Data, internal and external...
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 reset_after_external_interaction_field_fd()
Function that is call after the finite differencing of the external interaction data associated with ...
void disable_shear_stress_in_jacobian()
Call this function to ignore shear stress component of load when calculating the Jacobian,...
void include_external_load_data()
Include all external fluid data that affects the load in the computation of the element's Jacobian ma...
bool Ignore_shear_stress_in_jacobian
Set this flag to true to ignore shear stress component of load when calculating the Jacobian,...
void operator=(const FSIWallElement &)=delete
Broken assignment operator.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Fill in the element's contribution to the Jacobian matrix and the residual vector: Done by finite dif...
void update_in_external_fd(const unsigned &i)
After an external data change, update the nodal positions.
void enable_shear_stress_in_jacobian()
Call thi function to re-enable calculation of the shear stress componnent of load when calculating th...
void exclude_external_load_data()
Do not include any external data that affects the load in the computation of element's Jacobian matri...
const double & q() const
Return the ratio of the stress scales used to non-dimensionalise the fluid and solid equations....
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...
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...
void reset_after_internal_fd()
Function that is call after the finite differencing of the internal data. This may be overloaded to r...
void update_in_external_interaction_field_fd(const unsigned &i)
After an external field data change, update the nodal positions.
double * Q_pt
Pointer to the ratio, , of the stress used to non-dimensionalise the fluid stresses to the stress us...
static double Default_Q_Value
Static default value for the ratio of stress scales used in the fluid and solid equations (default is...
void reset_after_external_interaction_geometric_fd()
Function that is call after the finite differencing of the external interaction data associated with ...
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 update_in_nodal_fd(const unsigned &i)
After a nodal data change, update the nodal positions.
void update_in_solid_position_fd(const unsigned &i)
After an internal data change, update the nodal positions.
FSIWallElement()
Constructor. Note that element is not fully-functional until its setup_fsi_wall_element() function ha...
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.
void reset_after_solid_position_fd()
Function that is call after the finite differencing of the solid position data. This may be overloade...
void node_update_adjacent_fluid_elements()
Update the nodal positions in all fluid elements that affect the traction on this FSIWallElement.
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...
double *& q_pt()
Return a pointer the ratio of stress scales used to non-dimensionalise the fluid and solid equations.
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_nodal_fd(const unsigned &i)
Function called within the finite difference loop for nodal data after the i-th nodal values is reset...
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...
void describe_local_dofs(std::ostream &out, const std::string ¤t_string) const
Function to describe the local dofs of the element. The ostream specifies the output stream to which ...
A general Finite Element class.
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
virtual double s_min() const
Min value of local coordinate.
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...
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
unsigned dim() const
Return the spatial dimension of the element, i.e. the number of local coordinates required to paramet...
virtual double s_max() const
Max. value of local coordinate.
unsigned nodal_dimension() const
Return the required Eulerian dimension of the nodes in this 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...
bool is_halo() const
Is this element a halo?
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...
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...
unsigned ndof() const
Return the number of equations/dofs in the element.
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
virtual void get_residuals(Vector< double > &residuals)
Calculate the vector of residuals of the equations in the element. By default initialise the vector t...
unsigned ninternal_data() const
Return the number of internal data objects.
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
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...
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
unsigned long nnode() const
Return number of nodes in the mesh.
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
void output(std::ostream &outfile)
Output for all elements.
std::set< int > external_halo_proc()
Return the set of processors that hold external halo nodes. This is required to avoid having to pass ...
unsigned long nelement() const
Return number of elements in the mesh.
unsigned nexternal_halo_element()
Total number of external halo elements in this Mesh.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
double & x(const unsigned &i)
Return the i-th nodal coordinate.
An OomphLibError object which should be thrown when an run-time error is encountered....
An OomphLibWarning object which should be created as a temporary object to issue a warning....
////////////////////////////////////////////////////////////////// //////////////////////////////////...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
bool Solve_for_consistent_newmark_accel_flag
Flag to indicate which system of equations to solve when assigning initial conditions for time-depend...
virtual void fill_in_jacobian_from_solid_position_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Use finite differences to calculate the Jacobian entries corresponding to the solid positions....
void fill_in_jacobian_for_newmark_accel(DenseMatrix< double > &jacobian)
Fill in the contributions of the Jacobian matrix for the consistent assignment of the initial "accele...
SolidNode * node_pt(const unsigned long &n)
Return a pointer to the n-th global SolidNode.
Data *const & variable_position_pt() const
Pointer to variable_position data (const version)
double Strouhal_for_no_slip
Strouhal number St = a/(UT) for application of no slip condition. Initialised to 1....
void setup_solid_elements_for_displacement_bc(Problem *problem_pt, const Vector< unsigned > &b_solid_fsi, Mesh *const &solid_mesh_pt, Vector< Mesh * > &lagrange_multiplier_mesh_pt)
Setup multi-domain interaction required for imposition of solid displacements onto the pseudo-solid f...
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 = ...
void setup_fluid_load_info_for_solid_elements(Problem *problem_pt, Vector< unsigned > &boundary_in_fluid_mesh, Mesh *const &fluid_mesh_pt, Vector< Mesh * > &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 doc_fsi(Mesh *fluid_mesh_pt, SolidMesh *wall_mesh_pt, DocInfo &doc_info)
Doc FSI:
std::string string(const unsigned &i)
Return the i-th string or "" if the relevant string hasn't been defined.
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...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...