33 #ifndef OOMPH_REFINEABLE_ELASTICITY_ELEMENTS_HEADER 34 #define OOMPH_REFINEABLE_ELASTICITY_ELEMENTS_HEADER 38 #include "../generic/refineable_quad_element.h" 39 #include "../generic/refineable_brick_element.h" 40 #include "../generic/error_estimator.h" 48 template<
unsigned DIM>
67 const unsigned& flag);
81 return DIM + DIM*(DIM-1)/2;
89 unsigned num_entries=DIM+((DIM*DIM)-DIM)/2;
90 if (flux.size()!=num_entries)
92 std::ostringstream error_message;
93 error_message <<
"The flux vector has the wrong number of entries, " 94 << flux.size() <<
", whereas it should be " 95 << num_entries << std::endl;
97 OOMPH_CURRENT_FUNCTION,
98 OOMPH_EXCEPTION_LOCATION);
110 for(
unsigned i=0;
i<DIM;
i++)
112 flux[icount]=strain(
i,
i);
117 for(
unsigned i=0;
i<DIM;
i++)
119 for(
unsigned j=
i+1;j<DIM;j++)
121 flux[icount]=strain(
i,j);
171 template<
unsigned DIM,
unsigned NNODE_1D>
210 template<
unsigned NNODE_1D>
223 template<
unsigned NNODE_1D>
237 template<
unsigned NNODE_1D>
250 template<
unsigned NNODE_1D>
266 template<
unsigned DIM>
287 void fill_in_generic_residual_contribution_pvd_with_pressure(
290 const unsigned& flag);
304 return DIM + DIM*(DIM-1)/2;
314 unsigned num_entries=DIM+((DIM*DIM)-DIM)/2;
315 if (flux.size()!=num_entries)
317 std::ostringstream error_message;
318 error_message <<
"The flux vector has the wrong number of entries, " 319 << flux.size() <<
", whereas it should be " 320 << num_entries << std::endl;
322 OOMPH_CURRENT_FUNCTION,
323 OOMPH_EXCEPTION_LOCATION);
335 for(
unsigned i=0;
i<DIM;
i++)
337 flux[icount]=strain(
i,
i);
342 for(
unsigned i=0;
i<DIM;
i++)
344 for(
unsigned j=
i+1;j<DIM;j++)
346 flux[icount]=strain(
i,j);
406 template<
unsigned DIM>
420 for(
unsigned l=0;l<n_pres;l++)
499 using namespace QuadTreeNames;
502 double centre_solid_p[4]={0.0,0.0,0.0,0.0};
505 for (
unsigned ison=0;ison<4;ison++)
508 centre_solid_p[ison] =
510 (quadtree_pt()->son_pt(ison)->object_pt())->solid_p(0);
514 double p_value = 0.25*(centre_solid_p[0] + centre_solid_p[1] +
515 centre_solid_p[2] + centre_solid_p[3]);
517 set_solid_p(0,p_value);
527 double slope1=centre_solid_p[
SE] - centre_solid_p[
SW];
528 double slope2=centre_solid_p[
NE] - centre_solid_p[
NW];
532 p_value = 0.5*(slope1 + slope2);
533 set_solid_p(1,p_value);
543 slope1= centre_solid_p[
NE] - centre_solid_p[
SE];
544 slope2= centre_solid_p[
NW] - centre_solid_p[
SW];
547 p_value = 0.5*(slope1 + slope2);
548 set_solid_p(2,p_value);
561 using namespace QuadTreeNames;
564 int son_type=quadtree_pt()->son_type();
568 quadtree_pt()->father_pt()->object_pt();
581 else if (son_type==
SE)
587 else if (son_type==
NE)
594 else if (son_type==
NW)
606 set_solid_p(0,press);
609 set_solid_p(1,0.5*cast_father_element_pt->
solid_p(1));
610 set_solid_p(2,0.5*cast_father_element_pt->
solid_p(2));
621 using namespace OcTreeNames;
624 double centre_solid_p[8]= {0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
627 for(
unsigned ison=0;ison<8;ison++)
629 centre_solid_p[ison] =
630 octree_pt()->son_pt(ison)->object_pt()->
643 for (
unsigned ison=0;ison<8;ison++)
645 av_press += centre_solid_p[ison];
650 set_value(0,0.125*av_press);
661 double slope1 = centre_solid_p[
RDF] - centre_solid_p[
LDF];
662 double slope2 = centre_solid_p[
RUF] - centre_solid_p[
LUF];
663 double slope3 = centre_solid_p[
RDB] - centre_solid_p[
LDB];
664 double slope4 = centre_solid_p[
RUB] - centre_solid_p[
LUB];
668 set_value(1,0.25*(slope1+slope2+slope3+slope4));
678 slope1 = centre_solid_p[
LUB] - centre_solid_p[
LDB];
679 slope2 = centre_solid_p[
RUB] - centre_solid_p[
RDB];
680 slope3 = centre_solid_p[
LUF] - centre_solid_p[
LDF];
681 slope4 = centre_solid_p[
RUF] - centre_solid_p[
RDF];
685 set_value(2,0.25*(slope1+slope2+slope3+slope4));
695 slope1 = centre_solid_p[
LUF] - centre_solid_p[
LUB];
696 slope2 = centre_solid_p[
RUF] - centre_solid_p[
RUB];
697 slope3 = centre_solid_p[
LDF] - centre_solid_p[
LDB];
698 slope4 = centre_solid_p[
RDF] - centre_solid_p[
RDB];
702 set_value(3,0.25*(slope1+slope2+slope3+slope4));
715 using namespace OcTreeNames;
718 int son_type=octree_pt()->son_type();
723 octree_pt()->father_pt()->object_pt());
728 for(
unsigned i=0;
i<3;
i++)
741 set_solid_p(0,press);
744 for(
unsigned i=1;
i<4;
i++)
746 set_solid_p(
i,0.5*cast_father_element_pt->
solid_p(
i));
784 template<
unsigned DIM>
820 values[0] = this->interpolated_solid_p(s);
830 values[0] = this->interpolated_solid_p(s);
839 unsigned n_node = this->
nnode();
841 for(
unsigned n=0;n<n_node;n++)
852 unsigned n_node = this->
nnode();
853 for(
unsigned l=0;l<n_node;l++)
862 for(
unsigned l=0;l<n_solid_pres;l++)
867 nod_pt->
unpin(solid_p_index);
902 else {
return this->
node_pt(n);}
942 unsigned total_index=0;
944 unsigned NNODE_1D = 2;
948 for(
unsigned i=0;
i<DIM;
i++)
958 index[
i] = NNODE_1D-1;
964 double float_index = 0.5*(1.0 + s[
i])*(NNODE_1D-1);
965 index[
i] = int(float_index);
968 double excess = float_index - index[
i];
978 total_index += index[
i]*
979 static_cast<unsigned>(pow(static_cast<float>(NNODE_1D),
980 static_cast<int>(
i)));
1001 if(value_id==0) {
return 2;}
1014 {
return static_cast<unsigned>(pow(2.0,static_cast<int>(DIM)));}
1015 else {
return this->
nnode();}
1022 const int &value_id)
const 1029 {
return this->solid_pshape(s,psi);}
1030 else {
return this->
shape(s,psi);}
1043 {
return this->
node_pt(this->Pconv[l]);}
double * Lambda_sq_pt
Timescale ratio (non-dim. density)
void unpin(const unsigned &i)
Unpin the i-th stored variable.
double value(const unsigned &i) const
Return i-th stored value. This function is not virtual so that it can be inlined. This means that if ...
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 unsigned &t, const Vector< double > &s, Vector< double > &values)
No values are interpolated in this element (pure solid)
bool is_jacobian_evaluated_by_fd() const
Return the flag indicating whether the jacobian is evaluated by fd.
Base class for finite elements that can compute the quantities that are required for the Z2 error est...
void get_strain(const Vector< double > &s, DenseMatrix< double > &strain) const
Return the strain tensor.
virtual RefineableElement * father_element_pt() const
Return a pointer to the father element.
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.
void get_interpolated_values(const unsigned &t, const Vector< double > &s, Vector< double > &values)
OK get the time-dependent verion.
void unpin_elemental_solid_pressure_dofs()
Unpin all solid pressure dofs.
void pin_elemental_redundant_nodal_solid_pressures()
Pin the redundant solid pressure.
void get_interpolated_values(const unsigned &t, const Vector< double > &s, Vector< double > &values)
No values are interpolated in this element (pure solid)
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 ...
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.
RefineablePVDEquationsWithPressure()
Constructor:
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...
void further_setup_hanging_nodes()
No additional hanging node procedures are required for the solid elements.
ConstitutiveLaw * Constitutive_law_pt
Pointer to the constitutive law.
double solid_p(const unsigned &l)
Return the lth pressure value.
virtual Node * solid_pressure_node_pt(const unsigned &l)
unsigned nrecovery_order()
Order of recovery shape functions for Z2 error estimation: Same order as shape functions.
Nodes are derived from Data, but, in addition, have a definite (Eulerian) position in a space of a gi...
void rebuild_from_sons(Mesh *&mesh_pt)
Empty rebuild from sons, no need to reconstruct anything here.
virtual int solid_p_nodal_index() const
Return the index at which the solid pressure is stored if it is stored at the nodes. If not stored at the nodes this will return a negative number.
bool is_hanging() const
Test whether the node is geometrically hanging.
double *& lambda_sq_pt()
Access function for pointer to timescale ratio (nondim density)
void rebuild_from_sons(Mesh *&mesh_pt)
Empty rebuild from sons, empty.
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
void pin(const unsigned &i)
Pin the i-th stored variable.
unsigned ncont_interpolated_values() const
Number of continuously interpolated values: 0 (pure solid problem)
bool Unsteady
Flag that switches inertia on/off.
bool is_incompressible() const
Return whether the material is incompressible.
Class for Refineable PVD equations.
unsigned ncont_interpolated_values() const
Number of continuously interpolated values: 0 (pure solid problem)
RefineablePVDEquations()
Constructor.
unsigned nrecovery_order()
Order of recovery shape functions for Z2 error estimation: Same order as shape functions.
void further_setup_hanging_nodes()
No additional hanging node procedures are required for discontinuous solid pressures.
void further_setup_hanging_nodes()
Perform additional hanging node procedures for variables that are not interpolated by all nodes...
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
virtual unsigned nvertex_node() const
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...
bool is_inertia_enabled() const
Access function to flag that switches inertia on/off (const version)
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
IsotropicGrowthFctPt & isotropic_growth_fct_pt()
Access function: Pointer to isotropic growth function.
virtual void further_build()
Further build: Pass the father's Use_undeformed_macro_element_for_new_lagrangian_coords flag down...
void rebuild_from_sons(Mesh *&mesh_pt)
Reconstruct the pressure from the sons Must be specialized for each dimension.
unsigned required_nvalue(const unsigned &n) const
Overload the number of additional solid dofs at each node, we shall always assign 1...
void get_Z2_flux(const Vector< double > &s, Vector< double > &flux)
in strain tensor.
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 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...
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...
unsigned nvertex_node() const
Number of vertex nodes in the element.
unsigned nrecovery_order()
Order of recovery shape functions for Z2 error estimation: Same order as shape functions.
Node * vertex_node_pt(const unsigned &j) const
Pointer to the j-th vertex node in the element.
unsigned nvertex_node() const
Number of vertex nodes in the element.
unsigned num_Z2_flux_terms()
Number of 'flux' terms for Z2 error estimation.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
static const double Node_location_tolerance
Default value for the tolerance to be used when locating nodes via local coordinates.
unsigned ncont_interpolated_values() const
Number of continuously interpolated values: 0 (pure solid problem)
RefineableQPVDElementWithPressure()
Constructor:
unsigned nvertex_node() const
Number of vertex nodes in the element.
bool Evaluate_jacobian_by_fd
Use FD to evaluate Jacobian.
RefineableQPVDElement()
Constructor:
virtual void rebuild_from_sons(Mesh *&mesh_pt)=0
Rebuild the element, e.g. set internal values in line with those of the sons that have now merged...
unsigned ncont_interpolated_values() const
Number of continuously interpolated values (1) solid pressure.
IsotropicGrowthFctPt Isotropic_growth_fct_pt
Pointer to isotropic growth function.
Node * solid_pressure_node_pt(const unsigned &l)
virtual unsigned nnode_1d() const
Return the number of nodes along one edge of the element Default is to return zero — must be overloa...
unsigned num_Z2_flux_terms()
Number of 'flux' terms for Z2 error estimation.
void get_interpolated_values(const Vector< double > &s, Vector< double > &values)
OK, interpolate the solid pressures.
void get_interpolated_values(const Vector< double > &s, Vector< double > &values)
No values are interpolated in this element (pure solid)
RefineableQPVDElementWithContinuousPressure()
Constructor:
Class for refineable QPVDElement elements.
void further_build()
Pass the generic stuff down to the sons.
void unpin_elemental_solid_pressure_dofs()
Unpin all pressure dofs.
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...
ConstitutiveLaw *& constitutive_law_pt()
Return the constitutive law pointer.
BodyForceFctPt Body_force_fct_pt
Pointer to body force function.
void get_interpolated_values(const Vector< double > &s, Vector< double > &values)
No values are interpolated in this element (pure solid)
virtual unsigned npres_solid() const
Return the number of solid pressure degrees of freedom Default is that there are no solid pressures...
virtual Node * solid_pressure_node_pt(const unsigned &l)
void further_build()
Further build: Interpolate the solid pressure values Again this must be specialised for each dimensio...
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...
double interpolated_solid_p(const Vector< double > &s)
Return the interpolated_solid_pressure.
BodyForceFctPt & body_force_fct_pt()
Access function: Pointer to body force function.
unsigned nnode() const
Return the number of nodes.
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...
void fill_in_generic_contribution_to_residuals_pvd(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Call the residuals including hanging node cases.
void further_build()
Further build function, pass the pointers down to the sons.
unsigned ninterpolating_node_1d(const int &value_id)
The number of 1d pressure nodes is 2, otherwise we have the positional nodes.