30 #ifndef OOMPH_RAVIART_THOMAS_DARCY_HEADER 31 #define OOMPH_RAVIART_THOMAS_DARCY_HEADER 35 #include <oomph-lib-config.h> 38 #include "../generic/elements.h" 39 #include "../generic/shape.h" 40 #include "../generic/error_estimator.h" 41 #include "../generic/projection.h" 51 template <
unsigned DIM>
92 for(
unsigned i=0;
i<n;
i++)
100 (*Source_fct_pt)(x,b);
117 (*Mass_source_fct_pt)(x,b);
138 virtual unsigned q_edge_index(
const unsigned &n)
const = 0;
148 virtual double q_edge(
const unsigned &n)
const = 0;
159 const unsigned &edge,
164 virtual double q_internal(
const unsigned &n)
const = 0;
167 virtual void set_q_edge(
const unsigned &n,
const double& value)=0;
170 virtual void set_q_internal(
const unsigned &n,
const double& value)=0;
186 Shape &q_basis)
const = 0;
190 Shape &div_q_basis_ds)
const = 0;
194 Shape &q_basis)
const 196 const unsigned n_node = this->
nnode();
197 Shape psi(n_node,DIM);
198 const unsigned n_q_basis = this->
nq_basis();
199 Shape q_basis_local(n_q_basis,DIM);
229 virtual int p_local_eqn(
const unsigned &n)
const = 0;
232 virtual double p_value(
const unsigned &n)
const = 0;
235 virtual unsigned np_basis()
const = 0;
239 Shape &p_basis)
const = 0;
245 virtual void set_p_value(
const unsigned &n,
const double& value)=0;
256 const Shape &q_basis_local,
258 Shape &q_basis)
const;
281 Shape q_basis(n_q_basis,DIM);
284 for(
unsigned i=0;
i<DIM;
i++)
287 for(
unsigned l=0;l<n_q_basis_edge;l++)
291 for(
unsigned l=n_q_basis_edge;l<n_q_basis;l++)
300 const unsigned i)
const 305 Shape q_basis(n_q_basis,DIM);
309 for(
unsigned l=0;l<n_q_basis_edge;l++)
311 q_i +=
q_edge(l)*q_basis(l,i);
313 for(
unsigned l=n_q_basis_edge;l<n_q_basis;l++)
315 q_i +=
q_internal(l-n_q_basis_edge)*q_basis(l,i);
328 unsigned n_node=
nnode();
329 const unsigned n_q_basis =
nq_basis();
333 Shape div_q_basis_ds(n_q_basis);
353 for(
unsigned l=0;l<n_q_basis_edge;l++)
355 div_q+=1.0/det*div_q_basis_ds(l)*
q_edge(l);
359 for(
unsigned l=n_q_basis_edge;l<n_q_basis;l++)
361 div_q+=1.0/det*div_q_basis_ds(l)*
q_internal(l-n_q_basis_edge);
386 Shape p_basis(n_p_basis);
395 for(
unsigned l=0;l<n_p_basis;l++)
436 void output(std::ostream &outfile,
const unsigned &nplot);
449 const unsigned &nplot,
486 Shape &div_q_basis_ds,
487 Shape &div_q_test_ds)
const = 0;
497 Shape &div_q_basis_ds,
498 Shape &div_q_test_ds)
const = 0;
525 template<
class DARCY_ELEMENT>
546 std::stringstream error_stream;
548 <<
"Darcy elements only store 2 fields so fld = " 549 << fld <<
" is illegal \n";
552 OOMPH_CURRENT_FUNCTION,
553 OOMPH_EXCEPTION_LOCATION);
564 unsigned nvalue=dat_pt->
nvalue();
565 for (
unsigned i=0;
i<nvalue;
i++)
567 data_values.push_back(std::make_pair(dat_pt,
i));
573 unsigned n=edge_dat_pt.size();
574 for (
unsigned j=0;j<n;j++)
576 unsigned nvalue=edge_dat_pt[j]->nvalue();
577 for (
unsigned i=0;
i<nvalue;
i++)
579 data_values.push_back(std::make_pair(edge_dat_pt[j],
i));
585 unsigned nvalue=int_dat_pt->
nvalue();
586 for (
unsigned i=0;
i<nvalue;
i++)
588 data_values.push_back(std::make_pair(int_dat_pt,
i));
610 std::stringstream error_stream;
612 <<
"Darcy elements only store two fields so fld = " 613 << fld <<
" is illegal\n";
616 OOMPH_CURRENT_FUNCTION,
617 OOMPH_EXCEPTION_LOCATION);
639 std::stringstream error_stream;
641 <<
"Darcy elements only store two fields so fld = " 642 << fld <<
" is illegal.\n";
645 OOMPH_CURRENT_FUNCTION,
646 OOMPH_EXCEPTION_LOCATION);
653 const unsigned n_dim=this->
dim();
654 const unsigned n_node = this->
nnode();
655 const unsigned n_q_basis = this->
nq_basis();
656 const unsigned n_p_basis = this->
np_basis();
659 Shape psi_geom(n_node), q_basis(n_q_basis,n_dim), q_test(n_q_basis,n_dim),
660 p_basis(n_p_basis), p_test(n_p_basis),
661 div_q_basis_ds(n_q_basis), div_q_test_ds(n_q_basis);
673 unsigned n=p_basis.nindex1();
674 for (
unsigned i=0;
i<n;
i++)
683 unsigned m=q_basis.nindex2();
684 for (
unsigned i=0;
i<n;
i++)
686 for (
unsigned j=0;j<m;j++)
688 psi(
i,j)=q_basis(
i,j);
707 std::stringstream error_stream;
709 <<
"Darcy elements only store two fields so fld = " 710 << fld <<
" is illegal\n";
713 OOMPH_CURRENT_FUNCTION,
714 OOMPH_EXCEPTION_LOCATION);
718 double return_value=0.0;
728 "Don't call this function for Darcy!",
729 OOMPH_CURRENT_FUNCTION,
730 OOMPH_EXCEPTION_LOCATION);
743 std::stringstream error_stream;
745 <<
"Darcy elements only store two fields so fld = " 746 << fld <<
" is illegal\n";
749 OOMPH_CURRENT_FUNCTION,
750 OOMPH_EXCEPTION_LOCATION);
754 unsigned return_value=0;
775 std::stringstream error_stream;
777 <<
"Darcy elements only store two fields so fld = " 778 << fld <<
" is illegal\n";
781 OOMPH_CURRENT_FUNCTION,
782 OOMPH_EXCEPTION_LOCATION);
809 void output(std::ostream &outfile,
const unsigned &nplot)
817 return std::max(this->Initial_Nvalue[n],
unsigned(1));
827 for(
unsigned j=0;j<3;j++)
838 const unsigned& flag)
844 unsigned n_dim=this->
dim();
850 unsigned fld=this->Projected_field;
853 const unsigned n_node = this->
nnode();
858 const unsigned n_value=nvalue_of_field(fld);
864 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
874 other_el_pt=this->external_element_pt(0,ipt);
876 other_s=this->external_element_local_coord(0,ipt);
882 int local_eqn=0, local_unknown=0;
885 switch(Projection_type)
893 "Trying to project Lagrangian coordinates in non-SolidElement\n",
894 OOMPH_CURRENT_FUNCTION,
895 OOMPH_EXCEPTION_LOCATION);
899 Shape psi(n_node,n_position_type);
914 double interpolated_xi_bar=
916 ->interpolated_xi(other_s,Projected_lagrangian);
919 for(
unsigned l=0;l<n_node;++l)
922 for(
unsigned k=0;k<n_position_type;++k)
931 residuals[local_eqn] +=
932 (interpolated_xi_proj - interpolated_xi_bar)*psi(l,k)*
W;
937 for(
unsigned l2=0;l2<n_node;l2++)
940 for(
unsigned k2=0;k2<n_position_type;k2++)
944 if(local_unknown >= 0)
946 jacobian(local_eqn,local_unknown)
947 += psi(l2,k2)*psi(l,k)*
W;
963 Shape psi(n_node,n_position_type);
974 double interpolated_x_proj = 0.0;
978 interpolated_x_proj = this->
interpolated_x(s,Projected_coordinate);
983 interpolated_x_proj = this->get_field(0,fld,s);
987 double interpolated_x_bar=
989 other_s,Projected_coordinate);
992 for(
unsigned l=0;l<n_node;++l)
995 for(
unsigned k=0;k<n_position_type;++k)
1011 if(n_position_type!=1)
1014 "Trying to project generalised positions not in SolidElement\n",
1015 OOMPH_CURRENT_FUNCTION,
1016 OOMPH_EXCEPTION_LOCATION);
1018 local_eqn = local_equation(fld,l);
1025 residuals[local_eqn] +=
1026 (interpolated_x_proj - interpolated_x_bar)*psi(l,k)*
W;
1031 for(
unsigned l2=0;l2<n_node;l2++)
1034 for(
unsigned k2=0;k2<n_position_type;k2++)
1039 local_unknown = solid_el_pt
1044 local_unknown = local_equation(fld,l2);
1047 if(local_unknown >= 0)
1049 jacobian(local_eqn,local_unknown)
1050 += psi(l2,k2)*psi(l,k)*
W;
1072 double J=jacobian_and_shape_of_field(fld,s,psi);
1080 double interpolated_value_proj = this->get_field(now,fld,s);
1083 double interpolated_value_bar =
1084 cast_el_pt->
get_field(Time_level_for_projection,fld,other_s);
1087 for(
unsigned l=0;l<n_value;l++)
1089 local_eqn = local_equation(fld,l);
1093 residuals[local_eqn] +=
1094 (interpolated_value_proj - interpolated_value_bar)*psi[l]*W;
1099 for(
unsigned l2=0;l2<n_value;l2++)
1101 local_unknown = local_equation(fld,l2);
1102 if(local_unknown >= 0)
1104 jacobian(local_eqn,local_unknown)
1105 += psi[l2]*psi[l]*
W;
1117 Shape psi(n_value,n_dim);
1120 double J=jacobian_and_shape_of_field(fld,s,psi);
1132 cast_el_pt->interpolated_q(other_s,q_bar);
1135 if (Time_level_for_projection!=0)
1137 std::stringstream error_stream;
1139 <<
"Darcy elements are steady!\n";
1142 OOMPH_CURRENT_FUNCTION,
1143 OOMPH_EXCEPTION_LOCATION);
1148 for(
unsigned l=0;l<n_value;l++)
1150 local_eqn = local_equation(fld,l);
1154 for (
unsigned i=0;
i<n_dim;
i++)
1157 residuals[local_eqn] +=
1158 (q_proj[
i] - q_bar[
i])*psi(l,
i)*
W;
1163 for(
unsigned l2=0;l2<n_value;l2++)
1165 local_unknown = local_equation(fld,l2);
1166 if(local_unknown >= 0)
1168 jacobian(local_eqn,local_unknown)
1169 += psi(l2,
i)*psi(l,
i)*
W;
1180 "Wrong field specified. This should never happen\n",
1181 OOMPH_CURRENT_FUNCTION,
1182 OOMPH_EXCEPTION_LOCATION);
1190 "Wrong type specificied in Projection_type. This should never happen\n",
1191 OOMPH_CURRENT_FUNCTION,
1192 OOMPH_EXCEPTION_LOCATION);
1207 template<
class ELEMENT>
unsigned num_Z2_flux_terms()
Number off flux terms for Z2 error estimator (use actual flux)
void mass_source(const Vector< double > &x, double &b) const
Indirect access to the mass source function - returns 0 if no mass source function has been set...
MassSourceFctPt & mass_source_fct_pt()
Access function: Pointer to mass source function.
Class implementing the generic maths of the Darcy equations using Raviart-Thomas elements with both e...
void interpolated_div_q(const Vector< double > &s, double &div_q) const
Calculate the FE representation of div q.
virtual void set_q_internal(const unsigned &n, const double &value)=0
Set the values of the internal degree of freedom.
void interpolated_p(const Vector< double > &s, double &p) const
Calculate the FE representation of p.
Base class for finite elements that can compute the quantities that are required for the Z2 error est...
void compute_error(std::ostream &outfile, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt, Vector< double > &error, Vector< double > &norm)
Compute the error between the FE solution and the exact solution using the H(div) norm for q and L^2 ...
void pin_superfluous_darcy_dofs()
Helper function to pin superfluous dofs; required because we introduce at least one dof per node to a...
unsigned nhistory_values_for_coordinate_projection()
Number of positional history values (Note: count includes current value!)
unsigned nvalue_of_field(const unsigned &fld)
Return number of values in field fld.
virtual void pin_q_internal_value(const unsigned &n)=0
Pin the nth internal q value.
Darcy upgraded to become projectable.
virtual unsigned face_index_of_q_edge_basis_fct(const unsigned &j) const =0
Return the face index associated with edge flux degree of freedom.
virtual Vector< double > edge_flux_interpolation_point(const unsigned &edge, const unsigned &n) const =0
Returns the local coordinate of nth flux interpolation point along an edge.
virtual void get_p_basis(const Vector< double > &s, Shape &p_basis) const =0
Return the pressure basis.
virtual double p_value(const unsigned &n) const =0
Return the nth pressure value.
void get_Z2_flux(const Vector< double > &s, Vector< double > &flux)
Z2 flux (use actual flux)
unsigned self_test()
Self test – empty for now.
Template-free Base class for projectable elements.
virtual int q_internal_local_eqn(const unsigned &n) const =0
Return the equation number of the n-th internal degree of freedom.
double jacobian_and_shape_of_field(const unsigned &fld, const Vector< double > &s, Shape &psi)
Return Jacobian of mapping and shape functions of field fld at local coordinate s.
virtual void face_local_coordinate_of_flux_interpolation_point(const unsigned &edge, const unsigned &n, Vector< double > &s) const =0
Compute the face element coordinates of the nth flux interpolation point along an edge...
A general Finite Element class.
TimeStepper *& position_time_stepper_pt()
Return a pointer to the position timestepper.
double interpolated_p(const Vector< double > &s) const
Calculate the FE representation of p and return it.
void output(std::ostream &outfile, const unsigned &nplot)
Output FE representation of soln as in underlying element.
virtual void fill_in_generic_residual_contribution(Vector< double > &residuals, DenseMatrix< double > &jacobian, bool flag)
Fill in residuals and, if flag==true, jacobian.
DarcyEquations()
Constructor.
virtual unsigned face_index_of_edge(const unsigned &j) const =0
Return the face index associated with specified edge.
SourceFctPt source_fct_pt() const
Access function: Pointer to body force function (const version)
SourceFctPt Source_fct_pt
Pointer to body force function.
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
void(* MassSourceFctPt)(const Vector< double > &x, double &f)
Mass source function pointer typedef.
virtual double weight(const unsigned &i) const =0
Return weight of i-th integration point.
void pin(const unsigned &i)
Pin the i-th stored variable.
void get_q_basis(const Vector< double > &s, Shape &q_basis) const
Returns the transformed basis at local coordinate s.
virtual unsigned nq_basis_internal() const =0
Return the number of internal basis functions for q.
void output_fct(std::ostream &outfile, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output FE representation of exact soln: x,y,q1,q2,div_q,p at Nplot^DIM plot points.
virtual unsigned q_internal_index() const =0
Return the index of the internal data where the q_internal degrees of freedom are stored...
unsigned nnodal_position_type() const
Return the number of coordinate types that the element requires to interpolate the geometry between t...
virtual double local_to_eulerian_mapping(const DShape &dpsids, DenseMatrix< double > &jacobian, DenseMatrix< double > &inverse_jacobian) const
Calculate the mapping from local to Eulerian coordinates, given the derivatives of the shape function...
virtual Data * q_internal_data_pt() const =0
Return pointer to the Data object that stores the internal flux values.
double interpolated_q(const Vector< double > &s, const unsigned i) const
Calculate the FE representation of the i-th component of q.
virtual double shape_basis_test_local(const Vector< double > &s, Shape &psi, Shape &q_basis, Shape &q_test, Shape &p_basis, Shape &p_test, Shape &div_q_basis_ds, Shape &div_q_test_ds) const =0
Returns the geometric basis, and the q, p and divergence basis functions and test functions at local ...
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as ...
virtual double interpolated_x(const Vector< double > &s, const unsigned &i) const
Return FE interpolated coordinate x[i] at local coordinate s.
virtual int q_edge_local_eqn(const unsigned &n) const =0
Return the equation number of the n-th edge (flux) degree of freedom.
virtual void scale_basis(Shape &basis) const =0
Scale the edge basis to allow arbitrary edge mappings.
virtual unsigned nedge_flux_interpolation_point() const =0
Returns the number of flux interpolation points along each edge of the element.
virtual unsigned nq_basis_edge() const =0
Return the number of edge basis functions for q.
SourceFctPt & source_fct_pt()
Access function: Pointer to body force function.
double transform_basis(const Vector< double > &s, const Shape &q_basis_local, Shape &psi, Shape &q_basis) const
Performs a div-conserving transformation of the vector basis functions from the reference element to ...
virtual void pin_superfluous_darcy_dofs()
Helper function to pin superfluous dofs (empty; can be overloaded in projectable elements where we in...
unsigned required_nvalue(const unsigned &n) const
Overload required_nvalue to return at least one value.
unsigned nq_basis() const
Return the total number of computational basis functions for q.
Integral *const & integral_pt() const
Return the pointer to the integration scheme (const version)
virtual Vector< Data * > q_edge_data_pt() const =0
Return vector of pointers to the Data objects that store the edge flux values.
virtual unsigned np_basis() const =0
Return the total number of pressure basis functions.
virtual void pin_p_value(const unsigned &n)=0
Pin the nth pressure value.
void residual_for_projection(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag)
Residual for the projection step. Flag indicates if we want the Jacobian (1) or not (0)...
virtual void edge_flux_interpolation_point_global(const unsigned &j, Vector< double > &x) const =0
Compute the global coordinates of the flux_interpolation point associated with the j-th edge-based q ...
virtual double knot(const unsigned &i, const unsigned &j) const =0
Return local coordinate s[j] of i-th integration point.
unsigned nhistory_values_for_projection(const unsigned &fld)
Number of history values to be stored for fld-th field. (Note: count includes current value!) ...
void output(std::ostream &outfile)
Output with default number of plot points.
virtual unsigned q_edge_index(const unsigned &n) const =0
Return the nodal index at which the nth edge unknown is stored.
A class that represents a collection of data; each Data object may contain many different individual ...
virtual void dshape_local(const Vector< double > &s, Shape &psi, DShape &dpsids) const
Function to compute the geometric shape functions and derivatives w.r.t. local coordinates at local c...
virtual double q_internal(const unsigned &n) const =0
Return the values of the internal degree of freedom.
void interpolated_q(const Vector< double > &s, Vector< double > &q) const
Calculate the FE representation of q.
unsigned nfields_for_projection()
Number of fields to be projected: 2 (pressure and flux)
virtual unsigned required_nvalue(const unsigned &n) const =0
Number of values required at node n.
virtual Data * p_data_pt() const =0
Return pointer to the Data object that stores the pressure values.
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
int position_local_eqn(const unsigned &n, const unsigned &k, const unsigned &j) const
Access function that returns the local equation number that corresponds to the j-th coordinate of the...
void output(std::ostream &outfile)
Output with default number of plot points.
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Fill in contribution to residuals for the Darcy equations.
unsigned ntstorage() const
Return the number of doubles required to represent history (one for steady)
virtual void set_q_edge(const unsigned &n, const double &value)=0
Set the values of the edge (flux) degree of freedom.
virtual double q_edge(const unsigned &n) const =0
Return the values of the n-th edge (flux) degree of freedom.
unsigned ntstorage() const
Return total number of doubles stored per value to record time history of each value (one for steady ...
double get_field(const unsigned &t, const unsigned &fld, const Vector< double > &s)
Return interpolated field fld at local coordinate s, at time level t (t=0: present; t>0: history valu...
virtual void get_q_basis_local(const Vector< double > &s, Shape &q_basis) const =0
Returns the local form of the q basis 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 void get_div_q_basis_local(const Vector< double > &s, Shape &div_q_basis_ds) const =0
Returns the local form of the q basis and dbasis/ds at local coordinate s.
double interpolated_div_q(const Vector< double > &s)
Calculate the FE representation of div q and return it.
virtual unsigned nweight() const =0
Return the number of integration points of the scheme.
virtual double shape_basis_test_local_at_knot(const unsigned &ipt, Shape &psi, Shape &q_basis, Shape &q_test, Shape &p_basis, Shape &p_test, Shape &div_q_basis_ds, Shape &div_q_test_ds) const =0
Returns the geometric basis, and the q, p and divergence basis functions and test functions at integr...
void output_with_projected_flux(std::ostream &outfile, const unsigned &nplot, const Vector< double > unit_normal)
Output incl. projection of fluxes into direction of the specified unit vector.
virtual double get_field(const unsigned &time, const unsigned &fld, const Vector< double > &s)=0
Return the fld-th field at local coordinates s at time-level time (time=0: current value; time>0: his...
unsigned nindex1() const
Return the range of index 1 of the shape function object.
void source(const Vector< double > &x, Vector< double > &b) const
Indirect access to the source function - returns 0 if no source function has been set...
MassSourceFctPt mass_source_fct_pt() const
Access function: Pointer to mass source function (const version)
void(* SourceFctPt)(const Vector< double > &x, Vector< double > &f)
Source function pointer typedef.
ProjectableDarcyElement()
Constructor [this was only required explicitly from gcc 4.5.2 onwards...].
virtual unsigned q_edge_node_number(const unsigned &n) const =0
Return the number of the node where the nth edge unknown is stored.
Vector< std::pair< Data *, unsigned > > data_values_of_field(const unsigned &fld)
Specify the values associated with field fld. The information is returned in a vector of pairs which ...
virtual void set_p_value(const unsigned &n, const double &value)=0
Set the nth pressure value.
unsigned nnode() const
Return the number of nodes.
int local_equation(const unsigned &fld, const unsigned &j)
Return local equation number of value j in field fld.
virtual int p_local_eqn(const unsigned &n) const =0
Return the equation number of the n-th pressure degree of freedom.
SolidFiniteElement class.
virtual double J_eulerian(const Vector< double > &s) const
Return the Jacobian of mapping from local to global coordinates at local position s...
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...
MassSourceFctPt Mass_source_fct_pt
Pointer to the mass source function.
static DenseMatrix< double > Dummy_matrix
Empty dense matrix used as a dummy argument to combined residual and jacobian functions in the case w...