33 #ifndef OOMPH_SPECIFIC_NODE_UPDATE_INTERFACE_ELEMENTS_HEADER 34 #define OOMPH_SPECIFIC_NODE_UPDATE_INTERFACE_ELEMENTS_HEADER 38 #include <oomph-lib-config.h> 42 #include "../generic/Qelements.h" 43 #include "../generic/spines.h" 44 #include "../generic/hijacked_elements.h" 58 template<
class ELEMENT>
74 template<
class ELEMENT>
81 std::ostringstream error_message;
84 "The generic FluidInterfaceAdditionalValues<ELEMENT> class has been\n" 86 "called. This should never happen. If you are creating your own\n" 88 "surface equations you must overload the policy class to specify\n" 90 "how many additional values are required at the surface nodes.\n" 92 "For an example, see src/fluid_interface/surfactant_transport_elements.h\n" 95 OOMPH_CURRENT_FUNCTION,
96 OOMPH_EXCEPTION_LOCATION);
107 {error_message();
return 0;}
152 template<
class EQUATION_CLASS,
class DERIVATIVE_CLASS,
class ELEMENT>
154 public virtual Hijacked<SpineElement<FaceGeometry<ELEMENT> > >,
155 public virtual EQUATION_CLASS,
public DERIVATIVE_CLASS
163 {
return this->spine_local_eqn(n);}
171 it!=bulk_node_number.end();++it)
174 delete this->hijack_nodal_spine_value(*it,0);
186 DShape &surface_divergence)
187 {
return DERIVATIVE_CLASS::compute_surface_derivatives(
188 psi,dpsids,interpolated_t,interpolated_x,surface_gradient,
189 surface_divergence);}
198 const int &face_index,
199 const unsigned &
id=0) :
201 EQUATION_CLASS(), DERIVATIVE_CLASS()
212 if (this->has_hanging_nodes())
215 "This interface element will not work correctly if nodes are hanging\n",
216 OOMPH_CURRENT_FUNCTION,
217 OOMPH_EXCEPTION_LOCATION);
224 ELEMENT* cast_element_pt =
dynamic_cast<ELEMENT*
>(element_pt);
226 const unsigned n_u_index = cast_element_pt->n_u_nst();
227 this->U_index_interface.resize(n_u_index);
228 for(
unsigned i=0;
i<n_u_index;
i++)
230 this->U_index_interface[
i] = cast_element_pt->u_index_nst(
i);
234 unsigned n_node_face = this->nnode();
238 *interface_additional_values_pt =
243 bool add_values =
false;
247 for(
unsigned i=0;
i<n_node_face;++
i)
252 add_values |= additional_data_values[
i];
259 this->add_additional_values(additional_data_values,
id);
265 delete interface_additional_values_pt; interface_additional_values_pt=0;
273 EQUATION_CLASS::fill_in_generic_residual_contribution_interface(residuals,jacobian,1);
276 this->fill_in_jacobian_from_geometric_data(jacobian);
285 const unsigned &flag,
289 const DShape &dpsifdS_div,
296 EQUATION_CLASS::add_additional_residual_contributions_interface(
297 residuals,jacobian,flag,psif,dpsifds,dpsifdS,dpsifdS_div,s,interpolated_x,interpolated_n,W,J);
304 void output(std::ostream &outfile,
const unsigned &n_plot)
311 void output(FILE* file_pt,
const unsigned &n_plot)
321 const int &face_index)
326 DERIVATIVE_CLASS,ELEMENT> > *face_el_pt =
328 DERIVATIVE_CLASS,ELEMENT> >;
331 this->build_face_element(face_index,face_el_pt);
334 face_el_pt->u_index_interface_boundary() = this->U_index_interface;
343 const unsigned n_node_bounding = face_el_pt->nnode();
344 for(
unsigned n=0;n<n_node_bounding;n++)
346 face_el_pt->nbulk_value(n) =
347 face_el_pt->node_pt(n)->nvalue();
352 std::set<Data*> unique_additional_geom_data;
355 this->assemble_set_of_all_geometric_data(unique_additional_geom_data);
358 std::set<Data*> unique_face_geom_data_pt;
359 face_el_pt->assemble_set_of_all_geometric_data(unique_face_geom_data_pt);
362 for(std::set<Data*>::iterator it=unique_face_geom_data_pt.begin();
363 it!=unique_face_geom_data_pt.end();++it)
364 {unique_additional_geom_data.erase(*it);}
367 for(std::set<Data*>::iterator it = unique_additional_geom_data.begin();
368 it!= unique_additional_geom_data.end();++it)
370 face_el_pt->add_external_data(*it);
383 template<
class ELEMENT>
385 public Hijacked< SpineElement<FaceGeometry<FaceGeometry<ELEMENT> > > >,
401 void output(std::ostream &outfile,
const unsigned &n_plot)
408 void output(FILE* file_pt,
const unsigned &n_plot)
416 this->fill_in_generic_residual_contribution_interface_boundary(residuals,
419 this->fill_in_jacobian_from_external_by_fd(jacobian);
422 this->fill_in_jacobian_from_geometric_data(jacobian);
428 {
return this->spine_local_eqn(n);}
437 template<
class ELEMENT>
439 Hijacked<SpineElement<FaceGeometry<FaceGeometry<ELEMENT> > > >,
454 void output(std::ostream &outfile,
const unsigned &n_plot)
461 void output(FILE* file_pt,
const unsigned &n_plot)
470 this->fill_in_generic_residual_contribution_interface_boundary(residuals,
473 this->fill_in_jacobian_from_external_by_fd(jacobian);
476 this->fill_in_jacobian_from_geometric_data(jacobian);
484 return this->spine_local_eqn(n);
494 template<
class ELEMENT>
497 LineDerivatives,ELEMENT>
503 const int &face_index) :
510 template<
class ELEMENT>
524 template<
class ELEMENT>
527 AxisymmetricDerivatives,ELEMENT>
533 const int &face_index) :
539 template<
class ELEMENT>
552 template<
class ELEMENT>
555 SurfaceDerivatives,ELEMENT>
561 const int &face_index) :
567 template<
class ELEMENT>
594 template<
class EQUATION_CLASS,
class DERIVATIVE_CLASS,
class ELEMENT>
596 public virtual Hijacked<FaceGeometry<ELEMENT> >,
597 public EQUATION_CLASS,
public DERIVATIVE_CLASS
609 {
return this->Lagrange_index[n];}
616 return this->nodal_local_eqn(n,this->lagrange_index(n));
626 it!=bulk_node_number.end();++it)
629 delete this->hijack_nodal_value(*it,this->lagrange_index(*it));
641 DShape &surface_divergence)
642 {
return DERIVATIVE_CLASS::compute_surface_derivatives(
643 psi,dpsids,interpolated_t,interpolated_x,surface_gradient,
644 surface_divergence);}
655 const int &face_index,
656 const unsigned &
id=0) :
657 FaceGeometry<ELEMENT>(), EQUATION_CLASS(), DERIVATIVE_CLASS()
669 if (this->has_hanging_nodes())
672 "This flux element will not work correctly if nodes are hanging\n",
673 OOMPH_CURRENT_FUNCTION,
674 OOMPH_EXCEPTION_LOCATION);
681 ELEMENT* cast_element_pt =
dynamic_cast<ELEMENT*
>(element_pt);
682 const unsigned n_u_index = cast_element_pt->n_u_nst();
683 this->U_index_interface.resize(n_u_index);
684 for(
unsigned i=0;
i<n_u_index;
i++)
686 this->U_index_interface[
i] = cast_element_pt->u_index_nst(
i);
690 unsigned n_node_face = this->nnode();
695 *interface_additional_values_pt =
701 for(
unsigned n=0;n<n_node_face;n++)
704 additional_data_values[n] = interface_additional_values_pt->
nadditional_values(n) + 1;
710 this->add_additional_values(additional_data_values,
id);
714 Lagrange_index.resize(n_node_face);
715 for(
unsigned n=0;n<n_node_face;++n)
717 Lagrange_index[n] = additional_data_values[n] -1 +
718 dynamic_cast<BoundaryNodeBase*
>(this->node_pt(n))->index_of_first_value_assigned_by_face_element(
id);
725 delete interface_additional_values_pt; interface_additional_values_pt=0;
732 const unsigned &
i)
const 738 return *this->node_pt(n)->value_pt(this->lagrange_index(n));
747 EQUATION_CLASS::fill_in_generic_residual_contribution_interface(residuals,jacobian,1);
750 this->fill_in_jacobian_from_solid_position_by_fd(jacobian);
757 void output(std::ostream &outfile,
const unsigned &n_plot)
764 void output(FILE* file_pt,
const unsigned &n_plot)
775 const unsigned &flag,
779 const DShape &dpsifdS_div,
786 EQUATION_CLASS::add_additional_residual_contributions_interface(
787 residuals,jacobian,flag,psif,dpsifds,dpsifdS,dpsifdS_div,s,interpolated_x,interpolated_n,W,J);
790 const unsigned n_node = this->nnode();
792 const unsigned nodal_dimension = this->nodal_dimension();
794 double interpolated_lagrange = 0.0;
795 for(
unsigned l=0;l<n_node;l++)
798 interpolated_lagrange += lagrange(l)*psif(l);
801 int local_eqn=0, local_unknown = 0;
804 for(
unsigned l=0;l<n_node;l++)
807 for(
unsigned i=0;
i<nodal_dimension;
i++)
811 local_eqn = this->position_local_eqn(l,0,
i);
815 residuals[local_eqn] -=
816 interpolated_lagrange*interpolated_n[
i]*psif(l)*J*
W;
822 for(
unsigned l2=0;l2<n_node;l2++)
826 local_unknown = this->kinematic_local_eqn(l2);
827 if(local_unknown >= 0)
829 jacobian(local_eqn,local_unknown) -=
830 psif(l2)*interpolated_n[
i]*psif(l)*J*
W;
847 const int &face_index)
851 DERIVATIVE_CLASS,ELEMENT> > *face_el_pt =
855 this->build_face_element(face_index,face_el_pt);
858 face_el_pt->u_index_interface_boundary() = this->U_index_interface;
864 const unsigned n_node_bounding = face_el_pt->nnode();
867 for(
unsigned n=0;n<n_node_bounding;n++)
869 face_el_pt->nbulk_value(n) =
870 face_el_pt->node_pt(n)->nvalue();
873 local_lagrange_index[n] = this->Lagrange_index[face_el_pt->bulk_node_number(n)];
877 face_el_pt->set_lagrange_index(local_lagrange_index);
880 std::set<SolidNode*> set_of_solid_nodes;
881 const unsigned n_node = this->nnode();
882 for(
unsigned n=0;n<n_node;n++)
884 set_of_solid_nodes.insert(static_cast<SolidNode*>(this->node_pt(n)));
889 for(
unsigned n=0;n<n_node_bounding;n++)
892 face_el_pt->nbulk_value(n) =
893 this->nbulk_value(face_el_pt->bulk_node_number(n));
896 set_of_solid_nodes.erase(static_cast<SolidNode*>(
897 face_el_pt->node_pt(n)));
901 for(std::set<SolidNode*>::iterator it=set_of_solid_nodes.begin();
902 it!=set_of_solid_nodes.end();++it)
904 face_el_pt->add_external_data((*it)->variable_position_pt());
918 template<
class ELEMENT>
933 {Lagrange_index = lagrange_index;}
941 const unsigned &
i)
const 954 void output(std::ostream &outfile,
const unsigned &n_plot)
961 void output(FILE* file_pt,
const unsigned &n_plot)
969 fill_in_generic_residual_contribution_interface_boundary(residuals,
972 this->fill_in_jacobian_from_external_by_fd(jacobian);
975 this->fill_in_jacobian_from_solid_position_by_fd(jacobian);
981 return this->nodal_local_eqn(n,this->Lagrange_index[n]);
990 template<
class ELEMENT>
1004 {Lagrange_index = lagrange_index;}
1016 const unsigned &
i)
const 1024 void output(std::ostream &outfile,
const unsigned &n_plot)
1033 void output(FILE* file_pt,
const unsigned &n_plot)
1041 fill_in_generic_residual_contribution_interface_boundary(residuals,jacobian,1);
1044 this->fill_in_jacobian_from_external_by_fd(jacobian);
1047 this->fill_in_jacobian_from_solid_position_by_fd(jacobian);
1055 return this->nodal_local_eqn(n,this->Lagrange_index[n]);
1065 template<
class ELEMENT>
1068 LineDerivatives,ELEMENT>
1074 const int &face_index,
const unsigned &
id=0) :
1080 template<
class ELEMENT>
1094 template<
class ELEMENT>
1097 AxisymmetricDerivatives,ELEMENT>
1103 const int &face_index,
const unsigned &
id=0) :
1106 element_pt,face_index,id) {}
1110 template<
class ELEMENT>
1124 template<
class ELEMENT>
1127 SurfaceDerivatives,ELEMENT>
1133 const int &face_index,
const unsigned &
id=0) :
1140 template<
class ELEMENT>
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the element's residual vector and Jacobian.
void add_additional_residual_contributions_interface(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag, const Shape &psif, const DShape &dpsifds, const DShape &dpsifdS, const DShape &dpsifdS_div, const Vector< double > &s, const Vector< double > &interpolated_x, const Vector< double > &interpolated_n, const double &W, const double &J)
Helper function to calculate the additional contributions These are those filled in by the particular...
SpinePointFluidInterfaceBoundingElement()
Constructor.
Spine version of the LineFluidInterfaceBoundingElement.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Fill in contribution to residuals and Jacobian.
Specialisation of the interface boundary constraint to a line.
void output(FILE *file_pt, const unsigned &n_plot)
C-style Output function.
void hijack_kinematic_conditions(const Vector< unsigned > &bulk_node_number)
Hijacking the kinematic condition corresponds to hijacking the variables associated with the spine he...
SpineLineFluidInterfaceBoundingElement()
Constructor.
void output(std::ostream &outfile)
Overload the output function.
Specialise the Elastic update case to axisymmetric equations.
Specific policy class for the FluidInterfaceElemetnts, which do not require any additional values at ...
virtual void output(std::ostream &outfile)
Output the element data — typically the values at the nodes in a format suitable for post-processing...
Specialise the elastic update template class to concrete 1D case.
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
Specify the value of nodal zeta from the face geometry The "global" intrinsic coordinate of the eleme...
SpineUpdateFluidInterfaceElement(FiniteElement *const &element_pt, const int &face_index, const unsigned &id=0)
Constructor, the arguments are a pointer to the "bulk" element and the index of the face to be create...
unsigned nadditional_values(const unsigned &n)
Specific interface that states how many additional values are required for the n-th node...
virtual FluidInterfaceBoundingElement * make_bounding_element(const int &face_index)
Create an "bounding" element of the type specified by the BoundingElementType policy class Here...
Specialise Elastic update case to the concrete 2D case.
double & lagrange(const unsigned &n)
Return the lagrange multiplier at local node n.
Vector< unsigned > Lagrange_index
Short Storage for the index of the Lagrange multiplier at the chosen nodes.
A general Finite Element class.
void output(std::ostream &outfile, const unsigned &n_plot)
Output the element.
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
In a FaceElement, the "global" intrinsic coordinate of the element along the boundary, when viewed as part of a compound geometric object is specified using the boundary coordinate defined by the mesh. Note: Boundary coordinates will have been set up when creating the underlying mesh, and their values will have been stored at the nodes.
Specialisation of the interface boundary constraint to a point.
int kinematic_local_eqn(const unsigned &n)
Equation number of the kinematic BC associated with node j. (This is the equation for the Lagrange mu...
int kinematic_local_eqn(const unsigned &n)
In spine elements, the kinematic condition is the equation used to determine the unknown spine height...
void output(std::ostream &outfile)
Overload the output function.
int kinematic_local_eqn(const unsigned &n)
Local eqn number of kinematic bc associated with local node n.
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
Specify the value of nodal zeta from the face geometry The "global" intrinsic coordinate of the eleme...
void set_lagrange_index(const Vector< unsigned > &lagrange_index)
Set the Id.
This policy class is used to associate specific bounding elements with specific FluidInterface elemen...
Generic Spine node update interface template class that can be combined with a given surface equation...
ElasticLineFluidInterfaceBoundingElement()
Constructor.
void setup_equation_indices(ELEMENT *const &element_pt, const unsigned &id)
Specify any additional index setup information that is required; i.e. the look-up schemes for the add...
void add_additional_residual_contributions_interface(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag, const Shape &psif, const DShape &dpsifds, const DShape &dpsifdS, const DShape &dpsifdS_div, const Vector< double > &s, const Vector< double > &interpolated_x, const Vector< double > &interpolated_n, const double &W, const double &J)
Helper function to calculate the additional contributions to be added at each integration point...
ElasticUpdateFluidInterfaceElement(FiniteElement *const &element_pt, const int &face_index, const unsigned &id=0)
Constructor, pass a pointer to the bulk element and the face index of the bulk element to which the e...
void setup_equation_indices(FluidInterfaceElement *const &element_pt, const unsigned &id)
Specify any additional index setup information that is required; i.e. the look-up schemes for the add...
double zeta_nodal(const unsigned &n, const unsigned &k, const unsigned &i) const
The "global" intrinsic coordinate of the element when viewed as part of a geometric object should be ...
A class that contains the information required by Nodes that are located on Mesh boundaries. A BoundaryNode of a particular type is obtained by combining a given Node with this class. By differentiating between Nodes and BoundaryNodes we avoid a lot of un-necessary storage in the bulk Nodes.
void output(std::ostream &outfile)
Overload the output function.
void output(std::ostream &outfile, const unsigned &n_plot)
Output the element.
void output(FILE *file_pt)
Overload the C-style output function.
void output(FILE *file_pt, const unsigned &n_plot)
C-style Output function.
virtual FluidInterfaceBoundingElement * make_bounding_element(const int &face_index)
Create an "bounding" element (here actually a 2D line element of type ElasticLineFluidInterfaceBoundi...
SpineLineFluidInterfaceElement(FiniteElement *const &element_pt, const int &face_index)
void output(FILE *file_pt)
Overload the C-style output function.
void output(std::ostream &outfile)
Overload the output function.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the contribution to the residuals and the jacobian.
ElasticLineFluidInterfaceElement(FiniteElement *const &element_pt, const int &face_index, const unsigned &id=0)
This policy class is used to allow additional values to be added to the nodes from new surface equati...
Pseudo-elasticity version of the LineFluidInterfaceBoundingElement.
void output(std::ostream &outfile, const unsigned &n_plot)
Output the element.
void output(FILE *file_pt, const unsigned &n_plot)
C-style Output function.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the elemental residual vector and Jacobian.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the jacobian.
void output(FILE *file_pt)
Overload the C-style output function.
void output(FILE *file_pt, const unsigned &n_plot)
C-style Output function.
Pseudo-elasticity version of the PointFluidInterfaceBoundingElement.
void output(std::ostream &outfile)
Overload the output function.
void output(std::ostream &outfile, const unsigned &n_plot)
Output the element.
int kinematic_local_eqn(const unsigned &n)
Set the kinematic local equation.
void output(FILE *file_pt, const unsigned &n_plot)
C-style Output function.
void output(std::ostream &outfile)
Output with default number of plot points.
void output(std::ostream &outfile, const unsigned &n_plot)
Output the element.
int kinematic_local_eqn(const unsigned &n)
Local eqn number of the kinematic bc associated with local node n.
Generic Elastic node update interface template class that can be combined with a given surface equati...
SpineSurfaceFluidInterfaceElement(FiniteElement *const &element_pt, const int &face_index)
ElasticSurfaceFluidInterfaceElement(FiniteElement *const &element_pt, const int &face_index, const unsigned &id=0)
ElasticPointFluidInterfaceBoundingElement()
Constructor.
void hijack_kinematic_conditions(const Vector< unsigned > &bulk_node_number)
Hijacking the kinematic condition corresponds to hijacking the variables associated with the Lagrange...
void set_lagrange_index(const Vector< unsigned > &lagrange_index)
Set the Id and offset.
void output(std::ostream &outfile)
Overload the output function.
int kinematic_local_eqn(const unsigned &n)
Return local equation number associated with the kinematic constraint for local node n...
unsigned nadditional_values(const unsigned &n)
Specific interface that states how many additional values are required for the n-th node...
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Calculate the elemental residual vector and the Jacobian.
The SpineElement<ELEMENT> class takes an existing element as a template parameter and adds the necess...
void output(std::ostream &outfile, const unsigned &n_plot)
Output the element.
Hijacked elements are elements in which one or more Data values that affect the element's residuals...
virtual void build_face_element(const int &face_index, FaceElement *face_element_pt)
Function for building a lower dimensional FaceElement on the specified face of the FiniteElement...
unsigned lagrange_index(const unsigned &n)
Return the index at which the lagrange multiplier is stored at the n-th node.
Vector< unsigned > Lagrange_index
Short Storage for the index of Lagrange multiplier.
void output(FILE *file_pt)
Overload the C-style output function.
ElasticAxisymmetricFluidInterfaceElement(FiniteElement *const &element_pt, const int &face_index, const unsigned &id=0)
void output(FILE *file_pt)
Overload the C-style output function.
void output(FILE *file_pt)
Overload the C-style output function.
double compute_surface_derivatives(const Shape &psi, const DShape &dpsids, const DenseMatrix< double > &interpolated_t, const Vector< double > &interpolated_x, DShape &surface_gradient, DShape &surface_divergence)
Fill in the specific surface derivative calculations by calling the appropriate class function...
double compute_surface_derivatives(const Shape &psi, const DShape &dpsids, const DenseMatrix< double > &interpolated_t, const Vector< double > &interpolated_x, DShape &surface_gradient, DShape &surface_divergence)
Fill in the specific surface derivative calculations by calling the appropriate function from the der...
Vector< unsigned > Lagrange_index
Storage for the location of the Lagrange multiplier (If other additional values have been added we ne...
SolidFiniteElement class.
SpineAxisymmetricFluidInterfaceElement(FiniteElement *const &element_pt, const int &face_index)
void output(std::ostream &outfile)
Overload the output function.
void output(FILE *file_pt, const unsigned &n_plot)
C-style Output function.
Spine version of the PointFluidInterfaceBoundingElement.