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;
1035 #ifdef OOMPH_HAS_MPI
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...
FiniteElement *& external_element_pt(const unsigned &interaction_index, const unsigned &ipt)
Access function to source element for specified interaction index at specified integration point.
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_interaction_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the contributions to the jacobian from all external interaction degrees of freedom (geometr...
bool Add_external_interaction_data
Boolean flag to indicate whether to include the external data.
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 identify_pressure_data(std::set< std::pair< Data *, unsigned >> &paired_pressure_data)=0
Add to the set paired_pressure_data pairs containing.
void operator=(const FSIFluidElement &)=delete
Broken assignment operator.
FSIFluidElement()
Constructor.
FSIFluidElement(const FSIFluidElement &)=delete
Broken copy constructor.
virtual void identify_load_data(std::set< std::pair< Data *, unsigned >> &paired_load_data)=0
Add to the set paired_load_data pairs containing.
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...
////////////////////////////////////////////////////////////////////////// //////////////////////////...
void enable_fluid_loading_on_both_sides()
Allow element to be loaded by fluid on both sides. (Resizes containers for lookup schemes and initial...
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 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 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 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...
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 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 ...
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...
const double & q() const
Return the ratio of the stress scales used to non-dimensionalise the fluid and solid equations....
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 ...
double *& q_pt()
Return a pointer the ratio of stress scales used to non-dimensionalise the fluid and solid equations.
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...
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.
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.
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
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.
FiniteElement * finite_element_pt(const unsigned &e) const
Upcast (downcast?) to FiniteElement (needed to access FiniteElement member functions).
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...
std::set< int > external_halo_proc()
Return the set of processors that hold external halo nodes. This is required to avoid having to pass ...
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
unsigned long nnode() const
Return number of nodes in the mesh.
void output(std::ostream &outfile)
Output for all elements.
Node *& node_pt(const unsigned long &n)
Return pointer to global node n.
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...
double & x(const unsigned &i)
Return the i-th nodal coordinate.
unsigned ndim() const
Return (Eulerian) spatial dimension of the node.
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...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...