33 #ifndef OOMPH_AXISYM_POROELASITICTY_FACE_ELEMENTS_HEADER 34 #define OOMPH_AXISYM_POROELASITICTY_FACE_ELEMENTS_HEADER 38 #include <oomph-lib-config.h> 55 namespace AxisymmetricPoroelasticityTractionElementHelper
66 unsigned n_dim=load.size();
67 for (
unsigned i=0;
i<n_dim;
i++) {load[
i]=0.0;}
96 template <
class ELEMENT>
107 void (*Traction_fct_pt)(
const double& time,
116 void (*Pressure_fct_pt)(
const double& time,
128 const unsigned& intpt,
133 Traction_fct_pt(time,x,n,traction);
142 const unsigned& intpt,
147 Pressure_fct_pt(time,x,n,pressure);
155 void fill_in_contribution_to_residuals_axisym_poroelasticity_face(
164 const int &face_index) :
170 ELEMENT* elem_pt =
dynamic_cast<ELEMENT*
>(element_pt);
172 if(elem_pt->dim()==3)
178 if (this->has_hanging_nodes())
181 "This flux element will not work correctly if nodes are hanging\n",
182 OOMPH_CURRENT_FUNCTION,
183 OOMPH_EXCEPTION_LOCATION);
213 {
return Traction_fct_pt;}
221 {
return Pressure_fct_pt;}
227 fill_in_contribution_to_residuals_axisym_poroelasticity_face(residuals);
237 fill_in_contribution_to_residuals_axisym_poroelasticity_face(residuals);
247 const unsigned &
i)
const 259 void output(std::ostream &outfile,
const unsigned &n_plot)
262 double time=node_pt(0)->time_stepper_pt()->time_pt()->time();
263 unsigned n_dim = this->nodal_dimension();
266 unsigned n_node = nnode();
273 DShape dpsids(n_node,n_dim-1);
276 outfile << this->tecplot_zone_string(n_plot);
279 unsigned num_plot_points=this->nplot_points(n_plot);
280 for (
unsigned iplot=0;iplot<num_plot_points;iplot++)
283 this->get_s_plot(iplot,n_plot,s);
286 this->dshape_local(s,psi,dpsids);
289 ELEMENT* bulk_pt=
dynamic_cast<ELEMENT*
>(bulk_element_pt());
290 s_bulk=local_coordinate_in_bulk(s);
294 this->interpolated_x(s,x);
298 outer_unit_normal(s,unit_normal);
301 bulk_pt->interpolated_u(s_bulk,disp);
305 bulk_pt->interpolated_du_dt(s_bulk,du_dt);
309 bulk_pt->interpolated_q(s_bulk,q);
312 const double permeability=bulk_pt->permeability();
325 for(
unsigned l=0;l<n_node;l++)
328 for(
unsigned i=0;
i<2;
i++)
331 unsigned u_nodal_index = bulk_pt->u_index_axisym_poroelasticity(
i);
333 interpolated_t1[
i] += this->nodal_position(l,
i)*dpsids(l,0);
334 interpolated_T1[
i] += (this->nodal_position(l,
i)+
335 nodal_value(l,u_nodal_index))*dpsids(l,0);
340 double J_undef = sqrt(1.0+
341 (interpolated_t1[0]*interpolated_t1[0])/
342 (interpolated_t1[1]*interpolated_t1[1]))*x[0];
346 double J_def = sqrt(1.0+
347 (interpolated_T1[0]*interpolated_T1[0])/
348 (interpolated_T1[1]*interpolated_T1[1]))*(x[0]+disp[0]);
370 double lagr_euler_translation_factor=
371 lagrangian_eulerian_translation_factor(s);
374 for(
unsigned i=0;
i<n_dim;
i++)
375 {outfile << x[
i] <<
" ";}
378 for(
unsigned i=0;
i<n_dim;
i++)
380 outfile << disp[
i] <<
" ";
384 for(
unsigned i=0;
i<n_dim;
i++)
386 outfile << traction[
i] <<
" ";
390 outfile << pressure <<
" ";
393 outfile << permeability*q[0] <<
" " 394 << permeability*q[1] <<
" ";
397 outfile << du_dt[0] <<
" " 401 outfile << du_dt[0]+permeability*q[0] <<
" " 402 << du_dt[1]+permeability*q[1] <<
" ";
405 outfile << unit_normal[0] <<
" " 406 << unit_normal[1] <<
" ";
409 outfile << bulk_pt->interpolated_div_q(s_bulk) <<
" ";
412 outfile << bulk_pt->interpolated_p(s_bulk) <<
" ";
415 outfile << J_undef <<
" ";
418 outfile << J_def <<
" ";
421 outfile << lagr_euler_translation_factor <<
" ";
423 outfile << std::endl;
427 this->write_tecplot_zone_footer(outfile,n_plot);
435 void output(FILE* file_pt,
const unsigned &n_plot)
453 unsigned n_dim = this->nodal_dimension();
456 unsigned n_node = nnode();
462 DShape dpsids(n_node,n_dim-1);
465 this->dshape_local(s,psi,dpsids);
468 ELEMENT* bulk_pt=
dynamic_cast<ELEMENT*
>(bulk_element_pt());
469 s_bulk=local_coordinate_in_bulk(s);
472 this->interpolated_x(s,x);
476 outer_unit_normal(s,unit_normal);
479 bulk_pt->interpolated_u(s_bulk,disp);
484 for(
unsigned l=0;l<n_node;l++)
487 for(
unsigned i=0;
i<2;
i++)
490 unsigned u_nodal_index = bulk_pt->u_index_axisym_poroelasticity(
i);
492 interpolated_t1[
i] += this->nodal_position(l,
i)*dpsids(l,0);
493 interpolated_T1[
i] += (this->nodal_position(l,
i)+
494 nodal_value(l,u_nodal_index))*dpsids(l,0);
499 double J_undef = sqrt(interpolated_t1[0]*interpolated_t1[0]+
500 interpolated_t1[1]*interpolated_t1[1])*x[0];
504 double J_def = sqrt(interpolated_T1[0]*interpolated_T1[0]+
505 interpolated_T1[1]*interpolated_T1[1])*(x[0]+disp[0]);
507 double return_val=1.0;
508 if (J_def!=0.0) return_val=J_undef/J_def;
516 void traction(
const double& time,
523 void pressure(
const double& time,
533 double& seepage_flux_contrib)
538 ELEMENT* bulk_el_pt=
dynamic_cast<ELEMENT*
>(bulk_element_pt());
541 const double permeability=bulk_el_pt->permeability();
544 const unsigned n_node = this->nnode();
551 const unsigned n_intpt = integral_pt()->nweight();
558 skeleton_flux_contrib=0.0;
559 seepage_flux_contrib=0.0;
560 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
563 s[0] = integral_pt()->knot(ipt,0);
566 double W = this->integral_pt()->weight(ipt);
569 this->dshape_local_at_knot(ipt,psi,dpsids);
574 for(
unsigned l=0;l<n_node;l++)
577 for(
unsigned i=0;
i<2;
i++)
579 interpolated_x[
i] += this->nodal_position(l,
i)*psi(l);
580 interpolated_t1[
i] += this->nodal_position(l,
i)*dpsids(l,0);
585 double tlength = interpolated_t1[0]*interpolated_t1[0] +
586 interpolated_t1[1]*interpolated_t1[1];
589 double J = sqrt(tlength)*interpolated_x[0];
593 outer_unit_normal(s,interpolated_normal);
596 s_bulk=this->local_coordinate_in_bulk(s);
600 bulk_el_pt->interpolated_q(s_bulk,q);
604 bulk_el_pt->interpolated_du_dt(s_bulk,du_dt);
608 x_bulk[0]=bulk_el_pt->interpolated_x(s_bulk,0);
609 x_bulk[1]=bulk_el_pt->interpolated_x(s_bulk,1);
610 double error=sqrt((interpolated_x[0]-x_bulk[0])*
611 (interpolated_x[0]-x_bulk[0])+
612 (interpolated_x[1]-x_bulk[1])*
613 (interpolated_x[1]-x_bulk[1]));
617 std::stringstream junk;
619 <<
"Gap between bulk and face element coordinate\n" 620 <<
"is suspiciously large: " 621 << error <<
"\nBulk at: " 622 << x_bulk[0] <<
" " << x_bulk[1] <<
"\n" 623 <<
"Face at: " << interpolated_x[0] <<
" " << interpolated_x[1] <<
"\n";
625 OOMPH_CURRENT_FUNCTION,
626 OOMPH_EXCEPTION_LOCATION);
632 double dudt_flux=0.0;
633 for(
unsigned i=0;
i<2;
i++)
635 q_flux+=permeability*q[
i]*interpolated_normal[
i];
636 dudt_flux+=du_dt[
i]*interpolated_normal[
i];
657 template<
class ELEMENT>
661 unsigned n_dim = this->nodal_dimension();
669 outer_unit_normal(s,unit_normal);
675 get_traction(time,ipt,x,unit_normal,traction);
683 template<
class ELEMENT>
687 unsigned n_dim = this->nodal_dimension();
695 outer_unit_normal(s,unit_normal);
701 get_pressure(time,ipt,x,unit_normal,pressure);
710 template<
class ELEMENT>
716 unsigned n_node = nnode();
719 double time=node_pt(0)->time_stepper_pt()->time_pt()->time();
723 unsigned n_position_type = this->nnodal_position_type();
724 if(n_position_type != 1)
727 "Poroelasticity equations are not yet implemented for more than one position type",
728 OOMPH_CURRENT_FUNCTION,
729 OOMPH_EXCEPTION_LOCATION);
734 unsigned n_dim = this->nodal_dimension();
738 ELEMENT* bulk_el_pt=
dynamic_cast<ELEMENT*
>(bulk_element_pt());
740 unsigned n_q_basis = bulk_el_pt->nq_basis();
741 unsigned n_q_basis_edge = bulk_el_pt->nq_basis_edge();
750 DShape dpsids(n_node,n_dim-1);
751 Shape q_basis(n_q_basis,n_dim);
754 unsigned n_intpt = integral_pt()->nweight();
760 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
763 double w = integral_pt()->weight(ipt);
766 dshape_local_at_knot(ipt,psi,dpsids);
769 for(
unsigned i=0;
i<n_dim-1;
i++)
771 s_face[
i] = integral_pt()->knot(ipt,
i);
773 s_bulk=local_coordinate_in_bulk(s_face);
776 ELEMENT* bulk_el_pt=
dynamic_cast<ELEMENT*
>(bulk_element_pt());
781 bulk_el_pt->get_q_basis(s_bulk,q_basis);
790 for(
unsigned l=0;l<n_node;l++)
793 for(
unsigned i=0;
i<n_dim;
i++)
796 const double x_local = nodal_position(l,
i);
797 interpolated_x[
i] += x_local*psi(l);
800 for(
unsigned j=0;j<n_dim-1;j++)
802 interpolated_A(j,
i) += x_local*dpsids(l,j);
809 for(
unsigned i=0;
i<n_dim-1;
i++)
811 for(
unsigned j=0;j<n_dim-1;j++)
817 for(
unsigned k=0;k<n_dim;k++)
819 A(
i,j) += interpolated_A(
i,k)*interpolated_A(j,k);
826 outer_unit_normal(ipt,interpolated_normal);
836 Adet = A(0,0)*A(1,1) - A(0,1)*A(1,0);
841 "Wrong dimension in AxisymmetricPoroelasticityTractionElement",
842 OOMPH_CURRENT_FUNCTION,
843 OOMPH_EXCEPTION_LOCATION);
848 double W = w*sqrt(Adet);
867 for(
unsigned l=0;l<n_node;l++)
870 for(
unsigned i=0;
i<n_dim;
i++)
873 this->nodal_local_eqn(l,bulk_el_pt->u_index_axisym_poroelasticity(
i));
878 residuals[local_eqn] -= traction[
i]*psi(l)*interpolated_x[0]*
W;
885 for(
unsigned l=0;l<n_q_basis_edge;l++)
887 local_eqn = this->nodal_local_eqn(1,bulk_el_pt->q_edge_index(l));
893 for(
unsigned i=0;
i<n_dim;
i++)
896 residuals[local_eqn] +=
897 pressure*q_basis(l,
i)*interpolated_normal[
i]*interpolated_x[0]*
W;
915 template <
class POROELASTICITY_BULK_ELEMENT,
class NAVIER_STOKES_BULK_ELEMENT>
918 <POROELASTICITY_BULK_ELEMENT>,
937 const double &
q()
const {
return *Q_pt;}
946 const unsigned& intpt,
952 NAVIER_STOKES_BULK_ELEMENT* ext_el_pt=
953 dynamic_cast<NAVIER_STOKES_BULK_ELEMENT*
>(external_element_pt(0,intpt));
957 unsigned n_dim = this->nodal_dimension();
961 this->outer_unit_normal(intpt,interpolated_normal);
965 ext_el_pt->traction(s_ext,interpolated_normal,traction_nst);
973 for(
unsigned i=0;
i<(n_dim-1);
i++)
975 s[
i] = integral_pt()->knot(intpt,
i);
978 this->interpolated_x(s,x_local);
982 x_bulk[0]=ext_el_pt->interpolated_x(s_ext,0);
983 x_bulk[1]=ext_el_pt->interpolated_x(s_ext,1);
984 double error=sqrt((x_local[0]-x_bulk[0])*(x_local[0]-x_bulk[0])+
985 (x_local[1]-x_bulk[1])*(x_local[1]-x_bulk[1]));
989 std::stringstream junk;
991 <<
"Gap between external and face element coordinate\n" 992 <<
"is suspiciously large:" 993 << error <<
" ( tol = " << tol <<
" ) " 994 <<
"\nExternal/bulk at: " 995 << x_bulk[0] <<
" " << x_bulk[1] <<
"\n" 996 <<
"Face at: " << x_local[0] <<
" " << x_local[1] <<
"\n";
998 OOMPH_CURRENT_FUNCTION,
999 OOMPH_EXCEPTION_LOCATION);
1006 const double q_value=q();
1011 traction[0]=q_value*traction_nst[0];
1012 traction[1]=q_value*traction_nst[1];
1018 const unsigned& intpt,
1024 NAVIER_STOKES_BULK_ELEMENT* ext_el_pt=
1025 dynamic_cast<NAVIER_STOKES_BULK_ELEMENT*
>(external_element_pt(0,intpt));
1029 unsigned n_dim = this->nodal_dimension();
1033 this->outer_unit_normal(intpt,interpolated_normal);
1037 ext_el_pt->traction(s_ext,interpolated_normal,traction_nst);
1040 const double q_value=q();
1045 pressure=-q_value*(interpolated_normal[0]*traction_nst[0]+
1046 interpolated_normal[1]*traction_nst[1]);
1055 const int &face_index) :
1058 face_index), Q_pt(&Default_Q_Value)
1062 this->set_ninteraction(1);
1071 void output(std::ostream &outfile,
const unsigned &n_plot)
1075 double time=node_pt(0)->time_stepper_pt()->time_pt()->time();
1076 unsigned n_dim = this->nodal_dimension();
1084 unsigned n_intpt = integral_pt()->nweight();
1087 outfile << this->tecplot_zone_string(n_intpt);
1090 for(
unsigned ipt=0;ipt<n_intpt;ipt++)
1093 for(
unsigned i=0;
i<n_dim-1;
i++)
1095 s[
i] = integral_pt()->knot(ipt,
i);
1099 this->interpolated_x(s,x);
1103 this->outer_unit_normal(s,unit_normal);
1106 POROELASTICITY_BULK_ELEMENT* bulk_pt=
1107 dynamic_cast<POROELASTICITY_BULK_ELEMENT*
>(this->bulk_element_pt());
1108 s_bulk=this->local_coordinate_in_bulk(s);
1111 const double local_permeability=bulk_pt->permeability();
1115 bulk_pt->interpolated_q(s_bulk,q);
1118 bulk_pt->interpolated_u(s_bulk,disp);
1122 this->get_traction(time,
1130 this->get_pressure(time,
1138 for(
unsigned i=0;
i<n_dim;
i++)
1139 {outfile << x[
i] <<
" ";}
1142 for(
unsigned i=0;
i<n_dim;
i++)
1144 outfile << disp[
i] <<
" ";
1148 for(
unsigned i=0;
i<n_dim;
i++)
1150 outfile << traction[
i] <<
" ";
1154 outfile << pressure <<
" ";
1157 outfile << local_permeability*q[0] <<
" " 1158 << local_permeability*q[1] <<
" ";
1162 bulk_pt->interpolated_du_dt(s_bulk,du_dt);
1163 outfile << du_dt[0] <<
" " 1167 outfile << du_dt[0]+local_permeability*q[0] <<
" " 1168 << du_dt[1]+local_permeability*q[1] <<
" ";
1171 outfile << unit_normal[0] <<
" " 1172 << unit_normal[1] <<
" ";
1175 outfile << bulk_pt->interpolated_div_q(s_bulk) <<
" ";
1178 outfile << bulk_pt->interpolated_p(s_bulk) <<
" ";
1179 outfile << std::endl;
1183 this->write_tecplot_zone_footer(outfile,n_plot);
1192 this->fill_in_contribution_to_residuals_axisym_poroelasticity_face
1196 fill_in_jacobian_from_external_interaction_by_fd(residuals,jacobian);
1204 template <
class POROELASTICITY_BULK_ELEMENT,
class NAVIER_STOKES_BULK_ELEMENT>
1206 <POROELASTICITY_BULK_ELEMENT, NAVIER_STOKES_BULK_ELEMENT>::Default_Q_Value=1.0;
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 ...
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Return the residuals.
void get_pressure(const double &time, const unsigned &intpt, const Vector< double > &x, const Vector< double > &n, double &pressure)
Get the pore fluid pressure from the neighbouring Navier-Stokes bulk element's stress.
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Fill in contribution from Jacobian.
FSILinearisedAxisymPoroelasticTractionElement()
Default constructor.
bool Allow_gap_in_FSI
Public boolean to allow gap between poro-elastic and Navier Stokes element in FSI computations...
const double & q() const
Return the ratio of the stress scales used to non-dimensionalise the fluid and poroelasticity equatio...
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)
Fill in contribution from Jacobian.
virtual void get_pressure(const double &time, const unsigned &intpt, const Vector< double > &x, const Vector< double > &n, double &pressure)
Get the pressure value: Pass number of integration point (dummy), Eulerrian coordinate and normal vec...
const double Pi
50 digits from maple
static double Default_Q_Value
Static default value for the ratio of stress scales used in the fluid and poroelasticity equations (d...
A general Finite Element class.
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.
void get_traction(const double &time, const unsigned &intpt, const Vector< double > &x, const Vector< double > &n, Vector< double > &traction)
Get the (combined) traction from the neighbouring Navier-Stokes bulk element's stress.
void output(std::ostream &outfile, const unsigned &n_plot)
Output function – overloaded version – ignores n_plot since fsi elements can only evaluate traction...
AxisymmetricPoroelasticityTractionElement()
Default constructor.
void output(FILE *file_pt)
C_style output function.
void traction(const double &time, const Vector< double > &s, Vector< double > &traction)
Compute traction vector at specified local coordinate Should only be used for post-processing; ignore...
double lagrangian_eulerian_translation_factor(const Vector< double > &s)
Ratio of lengths of line elements (or annular surface areas) in the undeformed and deformed configura...
virtual void get_traction(const double &time, const unsigned &intpt, const Vector< double > &x, const Vector< double > &n, Vector< double > &traction)
Get the traction vector: Pass number of integration point (dummy), Eulerrian coordinate and normal ve...
FSILinearisedAxisymPoroelasticTractionElement(FiniteElement *const &element_pt, const int &face_index)
Constructor, which takes a "bulk" element and the value of the index and its limit.
void pressure(const double &time, const Vector< double > &s, double &pressure)
Compute pressure value at specified local coordinate Should only be used for post-processing; ignores...
void Zero_pressure_fct(const double &time, const Vector< double > &x, const Vector< double > &N, double &load)
Default load function (zero pressure)
AxisymmetricPoroelasticityTractionElement(FiniteElement *const &element_pt, const int &face_index)
Constructor, which takes a "bulk" element and the value of the index and its limit.
double *& q_pt()
Return a pointer the ratio of stress scales used to non-dimensionalise the fluid and poroelastic equa...
void output(std::ostream &outfile)
Output with default number of plot points.
void(*&)(const double &time, const Vector< double > &x, const Vector< double > &n, double &pressure) pressure_fct_pt()
Reference to the pressure function pointer.
double * Q_pt
Pointer to the ratio, , of the stress used to non-dimensionalise the fluid stresses to the stress use...
void fill_in_contribution_to_residuals_axisym_poroelasticity_face(Vector< double > &residuals)
Helper function that actually calculates the residuals.
void(*&)(const double &time, const Vector< double > &x, const Vector< double > &n, Vector< double > &traction) traction_fct_pt()
Reference to the traction function pointer.
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...
void Zero_traction_fct(const double &time, const Vector< double > &x, const Vector< double > &N, Vector< double > &load)
Default load function (zero traction)
void contribution_to_total_porous_flux(double &skeleton_flux_contrib, double &seepage_flux_contrib)
Compute contributions to integrated porous flux over boundary: q_skeleton = u_displ / t n ds q_se...
void output(std::ostream &outfile, const unsigned &n_plot)
Output function.
void output(std::ostream &outfile)
Output function.