29 #ifndef OOMPH_REFINEABLE_ELASTICITY_ELEMENTS_HEADER
30 #define OOMPH_REFINEABLE_ELASTICITY_ELEMENTS_HEADER
34 #include "../generic/refineable_quad_element.h"
35 #include "../generic/refineable_brick_element.h"
36 #include "../generic/error_estimator.h"
43 template<
unsigned DIM>
62 const unsigned& flag);
83 return DIM + DIM * (DIM - 1) / 2;
91 unsigned num_entries = DIM + ((DIM * DIM) - DIM) / 2;
92 if (flux.size() != num_entries)
94 std::ostringstream error_message;
95 error_message <<
"The flux vector has the wrong number of entries, "
96 << flux.size() <<
", whereas it should be " << num_entries
99 OOMPH_CURRENT_FUNCTION,
100 OOMPH_EXCEPTION_LOCATION);
112 for (
unsigned i = 0;
i < DIM;
i++)
114 flux[icount] = strain(
i,
i);
119 for (
unsigned i = 0;
i < DIM;
i++)
121 for (
unsigned j =
i + 1; j < DIM; j++)
123 flux[icount] = strain(
i, j);
177 template<
unsigned DIM,
unsigned NNODE_1D>
223 template<
unsigned NNODE_1D>
236 template<
unsigned NNODE_1D>
250 template<
unsigned NNODE_1D>
263 template<
unsigned NNODE_1D>
279 template<
unsigned DIM>
303 const unsigned& flag);
324 return DIM + DIM * (DIM - 1) / 2;
334 unsigned num_entries = DIM + ((DIM * DIM) - DIM) / 2;
335 if (flux.size() != num_entries)
337 std::ostringstream error_message;
338 error_message <<
"The flux vector has the wrong number of entries, "
339 << flux.size() <<
", whereas it should be " << num_entries
342 OOMPH_CURRENT_FUNCTION,
343 OOMPH_EXCEPTION_LOCATION);
355 for (
unsigned i = 0;
i < DIM;
i++)
357 flux[icount] = strain(
i,
i);
362 for (
unsigned i = 0;
i < DIM;
i++)
364 for (
unsigned j =
i + 1; j < DIM; j++)
366 flux[icount] = strain(
i, j);
431 template<
unsigned DIM>
443 for (
unsigned l = 0; l < n_pres; l++)
535 using namespace QuadTreeNames;
538 double centre_solid_p[4] = {0.0, 0.0, 0.0, 0.0};
541 for (
unsigned ison = 0; ison < 4; ison++)
544 centre_solid_p[ison] =
546 quadtree_pt()->son_pt(ison)->object_pt())
551 double p_value = 0.25 * (centre_solid_p[0] + centre_solid_p[1] +
552 centre_solid_p[2] + centre_solid_p[3]);
554 set_solid_p(0, p_value);
564 double slope1 = centre_solid_p[
SE] - centre_solid_p[
SW];
565 double slope2 = centre_solid_p[
NE] - centre_solid_p[
NW];
569 p_value = 0.5 * (slope1 + slope2);
570 set_solid_p(1, p_value);
580 slope1 = centre_solid_p[
NE] - centre_solid_p[
SE];
581 slope2 = centre_solid_p[
NW] - centre_solid_p[
SW];
584 p_value = 0.5 * (slope1 + slope2);
585 set_solid_p(2, p_value);
598 using namespace QuadTreeNames;
601 int son_type = quadtree_pt()->son_type();
617 else if (son_type ==
SE)
623 else if (son_type ==
NE)
630 else if (son_type ==
NW)
642 set_solid_p(0, press);
645 set_solid_p(1, 0.5 * cast_father_element_pt->
solid_p(1));
646 set_solid_p(2, 0.5 * cast_father_element_pt->
solid_p(2));
657 using namespace OcTreeNames;
660 double centre_solid_p[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
663 for (
unsigned ison = 0; ison < 8; ison++)
665 centre_solid_p[ison] = octree_pt()
668 ->internal_data_pt(this->P_solid_internal_index)
678 double av_press = 0.0;
681 for (
unsigned ison = 0; ison < 8; ison++)
683 av_press += centre_solid_p[ison];
687 internal_data_pt(this->P_solid_internal_index)
688 ->set_value(0, 0.125 * av_press);
699 double slope1 = centre_solid_p[
RDF] - centre_solid_p[
LDF];
700 double slope2 = centre_solid_p[
RUF] - centre_solid_p[
LUF];
701 double slope3 = centre_solid_p[
RDB] - centre_solid_p[
LDB];
702 double slope4 = centre_solid_p[
RUB] - centre_solid_p[
LUB];
705 internal_data_pt(this->P_solid_internal_index)
706 ->set_value(1, 0.25 * (slope1 + slope2 + slope3 + slope4));
716 slope1 = centre_solid_p[
LUB] - centre_solid_p[
LDB];
717 slope2 = centre_solid_p[
RUB] - centre_solid_p[
RDB];
718 slope3 = centre_solid_p[
LUF] - centre_solid_p[
LDF];
719 slope4 = centre_solid_p[
RUF] - centre_solid_p[
RDF];
722 internal_data_pt(this->P_solid_internal_index)
723 ->set_value(2, 0.25 * (slope1 + slope2 + slope3 + slope4));
733 slope1 = centre_solid_p[
LUF] - centre_solid_p[
LUB];
734 slope2 = centre_solid_p[
RUF] - centre_solid_p[
RUB];
735 slope3 = centre_solid_p[
LDF] - centre_solid_p[
LDB];
736 slope4 = centre_solid_p[
RDF] - centre_solid_p[
RDB];
739 internal_data_pt(this->P_solid_internal_index)
740 ->set_value(3, 0.25 * (slope1 + slope2 + slope3 + slope4));
753 using namespace OcTreeNames;
756 int son_type = octree_pt()->son_type();
760 octree_pt()->father_pt()->object_pt());
765 for (
unsigned i = 0;
i < 3;
i++)
778 set_solid_p(0, press);
781 for (
unsigned i = 1;
i < 4;
i++)
783 set_solid_p(
i, 0.5 * cast_father_element_pt->
solid_p(
i));
821 template<
unsigned DIM>
883 unsigned n_node = this->
nnode();
885 for (
unsigned n = 0; n < n_node; n++)
898 unsigned n_node = this->
nnode();
899 for (
unsigned l = 0; l < n_node; l++)
908 for (
unsigned l = 0; l < n_solid_pres; l++)
913 nod_pt->
unpin(solid_p_index);
997 unsigned total_index = 0;
999 unsigned NNODE_1D = 2;
1003 for (
unsigned i = 0;
i < DIM;
i++)
1012 else if (
s[
i] == 1.0)
1014 index[
i] = NNODE_1D - 1;
1020 double float_index = 0.5 * (1.0 +
s[
i]) * (NNODE_1D - 1);
1021 index[
i] = int(float_index);
1024 double excess = float_index - index[
i];
1035 index[
i] *
static_cast<unsigned>(pow(
static_cast<float>(NNODE_1D),
1036 static_cast<int>(
i)));
1077 return static_cast<unsigned>(pow(2.0,
static_cast<int>(DIM)));
1081 return this->
nnode();
1089 const int& value_id)
const
1101 return this->
shape(s, psi);
void pin(const unsigned &i)
Pin the i-th stored variable.
void unpin(const unsigned &i)
Unpin the i-th stored variable.
Base class for finite elements that can compute the quantities that are required for the Z2 error est...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
virtual Node * get_node_at_local_coordinate(const Vector< double > &s) const
If there is a node at this local coordinate, return the pointer to the node.
virtual unsigned nvertex_node() const
Return the number of vertex nodes in this element. Broken virtual function in "pure" finite elements.
static const double Node_location_tolerance
Default value for the tolerance to be used when locating nodes via local coordinates.
virtual void shape(const Vector< double > &s, Shape &psi) const =0
Calculate the geometric shape functions at local coordinate s. This function must be overloaded for e...
unsigned nnode() const
Return the number of nodes.
virtual Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element. Broken virtual function in "pure" finite elements.
virtual unsigned nnode_1d() const
Return the number of nodes along one edge of the element Default is to return zero — must be overload...
virtual double local_one_d_fraction_of_node(const unsigned &n1d, const unsigned &i)
Get the local fraction of any node in the n-th position in a one dimensional expansion along the i-th...
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
bool is_hanging() const
Test whether the node is geometrically hanging.
static Vector< Vector< int > > Direction_to_vector
For each direction, i.e. a son_type (vertex), a face or an edge, this defines a vector that indicates...
An OomphLibError object which should be thrown when an run-time error is encountered....
bool Unsteady
Flag that switches inertia on/off.
BodyForceFctPt Body_force_fct_pt
Pointer to body force function.
bool is_jacobian_evaluated_by_fd() const
Return the flag indicating whether the jacobian is evaluated by fd.
BodyForceFctPt & body_force_fct_pt()
Access function: Pointer to body force function.
ConstitutiveLaw *& constitutive_law_pt()
Return the constitutive law pointer.
ConstitutiveLaw * Constitutive_law_pt
Pointer to the constitutive law.
bool is_inertia_enabled() const
Access function to flag that switches inertia on/off (const version)
double *& lambda_sq_pt()
Access function for pointer to timescale ratio (nondim density)
void get_strain(const Vector< double > &s, DenseMatrix< double > &strain) const
Return the strain tensor.
IsotropicGrowthFctPt Isotropic_growth_fct_pt
Pointer to isotropic growth function.
bool Evaluate_jacobian_by_fd
Use FD to evaluate Jacobian.
IsotropicGrowthFctPt & isotropic_growth_fct_pt()
Access function: Pointer to isotropic growth function.
double * Lambda_sq_pt
Timescale ratio (non-dim. density)
//////////////////////////////////////////////////////////////////// ////////////////////////////////...
double interpolated_solid_p(const Vector< double > &s)
Return the interpolated_solid_pressure.
bool Incompressible
Boolean to determine whether the solid is incompressible or not.
bool is_incompressible() const
Return whether the material is incompressible.
A class for elements that solve the equations of solid mechanics, based on the principle of virtual d...
/////////////////////////////////////////////////////////////////////// /////////////////////////////...
//////////////////////////////////////////////////////////////////////// ////////////////////////////...
unsigned npres_solid() const
Return number of pressure values.
void solid_pshape(const Vector< double > &s, Shape &psi) const
Return the pressure shape functions.
int solid_p_nodal_index() const
Set the value at which the solid pressure is stored in the nodes.
static const unsigned Pconv[]
Static array of ints to hold conversion from pressure node numbers to actual node numbers.
/////////////////////////////////////////////////////////////////////////// /////////////////////////...
unsigned npres_solid() const
Return number of pressure values.
double solid_p(const unsigned &l)
Return the lth pressure value.
unsigned P_solid_internal_index
Internal index that indicates at which internal data value the solid presure is stored.
An Element that solves the solid mechanics equations, based on the principle of virtual displacements...
RefineableElements are FiniteElements that may be subdivided into children to provide a better local ...
static void check_value_id(const int &n_continuously_interpolated_values, const int &value_id)
Static helper function that is used to check that the value_id is in range.
virtual RefineableElement * father_element_pt() const
Return a pointer to the father element.
Class for Refineable solid mechanics elements in near-incompressible/ incompressible formulation,...
void get_interpolated_values(const unsigned &t, const Vector< double > &s, Vector< double > &values)
No values are interpolated in this element (pure solid)
unsigned ncont_interpolated_values() const
Number of continuously interpolated values: 0 (pure solid problem)
unsigned num_Z2_flux_terms()
Number of 'flux' terms for Z2 error estimation.
void get_Z2_flux(const Vector< double > &s, Vector< double > &flux)
in strain tensor.
void get_interpolated_values(const Vector< double > &s, Vector< double > &values)
No values are interpolated in this element (pure solid)
virtual Node * solid_pressure_node_pt(const unsigned &l)
void fill_in_generic_residual_contribution_pvd_with_pressure(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix, const unsigned &flag)
Add element's contribution to elemental residual vector and/or Jacobian matrix flag=1: compute both f...
void further_build()
Pass the generic stuff down to the sons.
void get_mass_matrix_diagonal(Vector< double > &mass_diag)
Compute the diagonal of the displacement mass matrix for LSC preconditioner.
RefineablePVDEquationsWithPressure()
Constructor:
Class for Refineable PVD equations.
RefineablePVDEquations()
Constructor.
unsigned num_Z2_flux_terms()
Number of 'flux' terms for Z2 error estimation.
void get_Z2_flux(const Vector< double > &s, Vector< double > &flux)
Get 'flux' for Z2 error recovery: Upper triangular entries in strain tensor.
void get_interpolated_values(const Vector< double > &s, Vector< double > &values)
No values are interpolated in this element (pure solid)
virtual Node * solid_pressure_node_pt(const unsigned &l)
void further_build()
Further build function, pass the pointers down to the sons.
void get_interpolated_values(const unsigned &t, const Vector< double > &s, Vector< double > &values)
No values are interpolated in this element (pure solid)
void fill_in_generic_contribution_to_residuals_pvd(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Call the residuals including hanging node cases.
unsigned ncont_interpolated_values() const
Number of continuously interpolated values: 0 (pure solid problem)
Refineable version of QElement<3,NNODE_1D>.
Class for refineable solid mechanics elements in near-incompressible/ incompressible formulation,...
double local_one_d_fraction_of_interpolating_node(const unsigned &n1d, const unsigned &i, const int &value_id)
The pressure nodes are the corner nodes, so when value_id==0, the fraction is the same as the 1d node...
void rebuild_from_sons(Mesh *&mesh_pt)
Empty rebuild from sons, empty.
unsigned required_nvalue(const unsigned &n) const
Overload the number of additional solid dofs at each node, we shall always assign 1,...
void interpolating_basis(const Vector< double > &s, Shape &psi, const int &value_id) const
The basis interpolating the pressure is given by pshape(). / The basis interpolating the velocity is ...
unsigned ninterpolating_node(const int &value_id)
The number of pressure nodes is 2^DIM. The number of velocity nodes is the same as the number of geom...
unsigned nvertex_node() const
Number of vertex nodes in the element.
RefineableQPVDElementWithContinuousPressure()
Constructor:
void pin_elemental_redundant_nodal_solid_pressures()
Pin the redundant solid pressure.
Node * solid_pressure_node_pt(const unsigned &l)
void unpin_elemental_solid_pressure_dofs()
Unpin all pressure dofs.
Node * interpolating_node_pt(const unsigned &n, const int &value_id)
The pressure "nodes" are a subset of the nodes, so when value_id==0, the n-th pressure node is return...
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
unsigned ninterpolating_node_1d(const int &value_id)
The number of 1d pressure nodes is 2, otherwise we have the positional nodes.
unsigned nrecovery_order()
Order of recovery shape functions for Z2 error estimation: Same order as shape functions.
void get_interpolated_values(const Vector< double > &s, Vector< double > &values)
OK, interpolate the solid pressures.
Node * get_interpolating_node_at_local_coordinate(const Vector< double > &s, const int &value_id)
The velocity nodes are the same as the geometric nodes. The pressure nodes must be calculated by usin...
unsigned ncont_interpolated_values() const
Number of continuously interpolated values (1) solid pressure.
void further_setup_hanging_nodes()
Perform additional hanging node procedures for variables that are not interpolated by all nodes.
void get_interpolated_values(const unsigned &t, const Vector< double > &s, Vector< double > &values)
OK get the time-dependent verion.
Class for refineable solid mechanics elements in near-incompressible/ incompressible formulation,...
void further_setup_hanging_nodes()
No additional hanging node procedures are required for discontinuous solid pressures.
RefineableQPVDElementWithPressure()
Constructor:
unsigned nrecovery_order()
Order of recovery shape functions for Z2 error estimation: Same order as shape functions.
unsigned nvertex_node() const
Number of vertex nodes in the element.
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
unsigned ncont_interpolated_values() const
Number of continuously interpolated values: 0 (pure solid problem)
void rebuild_from_sons(Mesh *&mesh_pt)
Reconstruct the pressure from the sons Must be specialized for each dimension.
void unpin_elemental_solid_pressure_dofs()
Unpin all solid pressure dofs.
void further_build()
Further build: Interpolate the solid pressure values Again this must be specialised for each dimensio...
Class for refineable QPVDElement elements.
RefineableQPVDElement()
Constructor:
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
void further_setup_hanging_nodes()
No additional hanging node procedures are required for the solid elements.
unsigned nvertex_node() const
Number of vertex nodes in the element.
void rebuild_from_sons(Mesh *&mesh_pt)
Empty rebuild from sons, no need to reconstruct anything here.
unsigned nrecovery_order()
Order of recovery shape functions for Z2 error estimation: Same order as shape functions.
/////////////////////////////////////////////////////////////////// /////////////////////////////////...
virtual void further_build()
Further build: Pass the father's Use_undeformed_macro_element_for_new_lagrangian_coords flag down,...
A class that is used to template the solid refineable Q elements by dimension. It's really nothing mo...
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
SolidQElement elements are quadrilateral elements whose derivatives also include those based upon the...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...