31 template<
unsigned DIM>
35 template<
unsigned DIM>
39 template<
unsigned DIM>
43 template<
unsigned DIM>
47 template<
unsigned DIM>
53 template<
unsigned DIM>
58 if ((strain.
ncol() != DIM) || (strain.
nrow() != DIM))
60 std::ostringstream error_message;
61 error_message <<
"Strain matrix is " << strain.
ncol() <<
" x "
62 << strain.
nrow() <<
", but dimension of the equations is "
65 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
84 unsigned n_node = nnode();
87 unsigned u_nodal_index[DIM];
88 for (
unsigned i = 0;
i < DIM;
i++)
90 u_nodal_index[
i] = u_index(
i);
95 DShape dpsidx(n_node, DIM);
98 (void)dshape_eulerian(
s, psi, dpsidx);
104 for (
unsigned l = 0; l < n_node; l++)
107 for (
unsigned i = 0;
i < DIM;
i++)
110 const double u_value = this->nodal_value(l, u_nodal_index[
i]);
113 for (
unsigned j = 0; j < DIM; j++)
115 interpolated_dudx(
i, j) += u_value * dpsidx(l, j);
121 for (
unsigned i = 0;
i < DIM;
i++)
126 for (
int j = (DIM - 1); j >=
static_cast<int>(
i); j--)
129 if (
static_cast<int>(
i) != j)
132 0.5 * (interpolated_dudx(
i, j) + interpolated_dudx(j,
i));
137 strain(
i,
i) = interpolated_dudx(
i,
i);
141 for (
int j = (
i - 1); j >= 0; j--)
143 strain(
i, j) = strain(j,
i);
153 template<
unsigned DIM>
158 if ((stress.
ncol() != DIM) || (stress.
nrow() != DIM))
160 std::ostringstream error_message;
161 error_message <<
"Stress matrix is " << stress.
ncol() <<
" x "
162 << stress.
nrow() <<
", but dimension of the equations is "
165 error_message.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
171 this->get_strain(
s, strain);
176 for (
unsigned i = 0;
i < DIM;
i++)
178 for (
unsigned j = 0; j < DIM; j++)
181 for (
unsigned k = 0; k < DIM; k++)
183 for (
unsigned l = 0; k < DIM; k++)
185 stress(
i, j) += this->
E(
i, j, k, l) * strain(k, l);
195 template<
unsigned DIM>
198 const Shape& q_basis_local,
201 Shape& q_basis)
const
205 this->dshape_local(
s, psi, dpsi);
211 double det = local_to_eulerian_mapping(dpsi, jacobian, inverse_jacobian);
215 this->transform_derivatives(inverse_jacobian, dpsi);
218 const unsigned n_q_basis = this->nq_basis();
221 for (
unsigned l = 0; l < n_q_basis; l++)
224 for (
unsigned i = 0;
i < DIM;
i++)
232 for (
unsigned i = 0;
i < DIM;
i++)
235 for (
unsigned j = 0; j < DIM; j++)
239 double jac_trans = jacobian(j,
i) / det;
242 for (
unsigned l = 0; l < n_q_basis; l++)
245 q_basis(l,
i) += jac_trans * q_basis_local(l, j);
252 scale_basis(q_basis);
259 template<
unsigned DIM>
261 const unsigned& nplot)
267 outfile << tecplot_zone_string(nplot);
270 unsigned num_plot_points = nplot_points(nplot);
272 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
275 get_s_plot(iplot, nplot,
s);
278 for (
unsigned i = 0;
i < DIM;
i++)
280 outfile << interpolated_x(
s,
i) <<
" ";
284 for (
unsigned i = 0;
i < DIM;
i++)
286 outfile << interpolated_u(
s,
i) <<
" ";
290 for (
unsigned i = 0;
i < DIM;
i++)
292 outfile << interpolated_q(
s,
i) <<
" ";
296 outfile << interpolated_div_q(
s) <<
" ";
299 outfile << interpolated_p(
s) <<
" ";
301 const unsigned n_node = this->nnode();
308 for (
unsigned i = 0;
i < DIM;
i++)
310 for (
unsigned l = 0; l < n_node; l++)
312 interpolated_du_dt[
i] += du_dt(l,
i) * psi(l);
314 outfile << interpolated_du_dt[
i] <<
" ";
319 for (
unsigned i = 0;
i < DIM;
i++)
321 for (
unsigned l = 0; l < n_node; l++)
323 interpolated_d2u_dt2[
i] += d2u_dt2(l,
i) * psi(l);
325 outfile << interpolated_d2u_dt2[
i] <<
" ";
328 const unsigned n_q_basis = this->nq_basis();
329 const unsigned n_q_basis_edge = this->nq_basis_edge();
331 Shape q_basis(n_q_basis, DIM), q_basis_local(n_q_basis, DIM);
332 this->get_q_basis_local(
s, q_basis_local);
333 (void)this->transform_basis(
s, q_basis_local, psi, q_basis);
337 for (
unsigned i = 0;
i < DIM;
i++)
339 for (
unsigned l = 0; l < n_q_basis_edge; l++)
341 interpolated_dq_dt[
i] += dq_edge_dt(l) * q_basis(l,
i);
343 for (
unsigned l = n_q_basis_edge; l < n_q_basis; l++)
345 interpolated_dq_dt[
i] +=
346 dq_internal_dt(l - n_q_basis_edge) * q_basis(l,
i);
348 outfile << interpolated_dq_dt[
i] <<
" ";
351 outfile << std::endl;
355 this->write_tecplot_zone_footer(outfile, nplot);
360 template<
unsigned DIM>
362 std::ostream& outfile,
363 const unsigned& nplot,
373 outfile << this->tecplot_zone_string(nplot);
379 unsigned num_plot_points = this->nplot_points(nplot);
381 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
384 this->get_s_plot(iplot, nplot,
s);
387 this->interpolated_x(
s, x);
390 (*exact_soln_pt)(x, exact_soln);
393 for (
unsigned i = 0;
i < DIM;
i++)
395 outfile << x[
i] <<
" ";
397 for (
unsigned i = 0;
i < 2 * DIM + 2;
i++)
399 outfile << exact_soln[
i] <<
" ";
401 outfile << std::endl;
405 this->write_tecplot_zone_footer(outfile, nplot);
410 template<
unsigned DIM>
412 std::ostream& outfile,
413 const unsigned& nplot,
424 outfile << this->tecplot_zone_string(nplot);
430 unsigned num_plot_points = this->nplot_points(nplot);
432 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
435 this->get_s_plot(iplot, nplot,
s);
438 this->interpolated_x(
s, x);
441 (*exact_soln_pt)(time, x, exact_soln);
444 for (
unsigned i = 0;
i < DIM;
i++)
446 outfile << x[
i] <<
" ";
448 for (
unsigned i = 0;
i < 2 * DIM + 2;
i++)
450 outfile << exact_soln[
i] <<
" ";
452 outfile << std::endl;
456 this->write_tecplot_zone_footer(outfile, nplot);
461 template<
unsigned DIM>
463 std::ostream& outfile,
468 for (
unsigned i = 0;
i < 3;
i++)
481 unsigned n_intpt = this->integral_pt()->nweight();
483 outfile <<
"ZONE" << std::endl;
489 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
492 for (
unsigned i = 0;
i < DIM;
i++)
494 s[
i] = this->integral_pt()->knot(ipt,
i);
498 double w = this->integral_pt()->weight(ipt);
501 double J = this->J_eulerian(
s);
507 this->interpolated_x(
s, x);
510 (*exact_soln_pt)(x, exact_soln);
513 for (
unsigned i = 0;
i < DIM;
i++)
515 norm[0] += exact_soln[
i] * exact_soln[
i] *
W;
517 error[0] += (exact_soln[
i] - this->interpolated_u(
s,
i)) *
518 (exact_soln[
i] - this->interpolated_u(
s,
i)) *
W;
522 for (
unsigned i = 0;
i < DIM;
i++)
524 norm[1] += exact_soln[DIM +
i] * exact_soln[DIM +
i] *
W;
526 error[1] += (exact_soln[DIM +
i] - this->interpolated_q(
s,
i)) *
527 (exact_soln[DIM +
i] - this->interpolated_q(
s,
i)) *
W;
531 norm[1] += exact_soln[2 * DIM] * exact_soln[2 * DIM] *
W;
532 error[1] += (exact_soln[2 * DIM] - interpolated_div_q(
s)) *
533 (exact_soln[2 * DIM] - interpolated_div_q(
s)) *
W;
536 norm[2] += exact_soln[2 * DIM + 1] * exact_soln[2 * DIM + 1] *
W;
537 error[2] += (exact_soln[2 * DIM + 1] - this->interpolated_p(
s)) *
538 (exact_soln[2 * DIM + 1] - this->interpolated_p(
s)) *
W;
541 for (
unsigned i = 0;
i < DIM;
i++)
543 outfile << x[
i] <<
" ";
547 for (
unsigned i = 0;
i < DIM;
i++)
549 outfile << exact_soln[
i] - this->interpolated_u(
s,
i) <<
" ";
553 for (
unsigned i = 0;
i < DIM;
i++)
555 outfile << exact_soln[DIM +
i] - this->interpolated_q(
s,
i) <<
" ";
559 outfile << exact_soln[2 * DIM + 1] - this->interpolated_p(
s) <<
" ";
561 outfile << std::endl;
567 template<
unsigned DIM>
569 std::ostream& outfile,
575 for (
unsigned i = 0;
i < 3;
i++)
588 unsigned n_intpt = this->integral_pt()->nweight();
590 outfile <<
"ZONE" << std::endl;
596 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
599 for (
unsigned i = 0;
i < DIM;
i++)
601 s[
i] = this->integral_pt()->knot(ipt,
i);
605 double w = this->integral_pt()->weight(ipt);
608 double J = this->J_eulerian(
s);
614 this->interpolated_x(
s, x);
617 (*exact_soln_pt)(time, x, exact_soln);
620 for (
unsigned i = 0;
i < DIM;
i++)
622 norm[0] += exact_soln[
i] * exact_soln[
i] *
W;
624 error[0] += (exact_soln[
i] - this->interpolated_u(
s,
i)) *
625 (exact_soln[
i] - this->interpolated_u(
s,
i)) *
W;
629 for (
unsigned i = 0;
i < DIM;
i++)
631 norm[1] += exact_soln[DIM +
i] * exact_soln[DIM +
i] *
W;
633 error[1] += (exact_soln[DIM +
i] - this->interpolated_q(
s,
i)) *
634 (exact_soln[DIM +
i] - this->interpolated_q(
s,
i)) *
W;
638 norm[1] += exact_soln[2 * DIM] * exact_soln[2 * DIM] *
W;
639 error[1] += (exact_soln[2 * DIM] - interpolated_div_q(
s)) *
640 (exact_soln[2 * DIM] - interpolated_div_q(
s)) *
W;
643 norm[2] += exact_soln[2 * DIM + 1] * exact_soln[2 * DIM + 1] *
W;
644 error[2] += (exact_soln[2 * DIM + 1] - this->interpolated_p(
s)) *
645 (exact_soln[2 * DIM + 1] - this->interpolated_p(
s)) *
W;
648 for (
unsigned i = 0;
i < DIM;
i++)
650 outfile << x[
i] <<
" ";
654 for (
unsigned i = 0;
i < DIM;
i++)
656 outfile << exact_soln[
i] - this->interpolated_u(
s,
i) <<
" ";
660 for (
unsigned i = 0;
i < DIM;
i++)
662 outfile << exact_soln[DIM +
i] - this->interpolated_q(
s,
i) <<
" ";
666 outfile << exact_soln[2 * DIM + 1] - this->interpolated_p(
s) <<
" ";
668 outfile << std::endl;
673 template<
unsigned DIM>
679 const unsigned n_node = nnode();
680 const unsigned n_q_basis = nq_basis();
681 const unsigned n_q_basis_edge = nq_basis_edge();
682 const unsigned n_p_basis = np_basis();
685 Shape psi(n_node), u_basis(n_node), u_test(n_node), q_basis(n_q_basis, DIM),
686 q_test(n_q_basis, DIM), p_basis(n_p_basis), p_test(n_p_basis),
687 div_q_basis_ds(n_q_basis), div_q_test_ds(n_q_basis);
689 DShape dpsidx(n_node, DIM), du_basis_dx(n_node, DIM),
690 du_test_dx(n_node, DIM);
693 unsigned n_intpt = integral_pt()->nweight();
705 double mass_source_local;
708 double lambda_sq = this->lambda_sq();
711 double k_inv = this->k_inv();
714 double alpha = this->alpha();
717 double porosity = this->porosity();
720 double density_ratio = this->density_ratio();
723 double rho_f_over_rho =
724 density_ratio / (1 + porosity * (density_ratio - 1));
727 double time = node_pt(0)->time_stepper_pt()->time_pt()->time();
730 int local_eqn = 0, local_unknown = 0;
733 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
736 for (
unsigned i = 0;
i < DIM;
i++)
738 s[
i] = integral_pt()->knot(ipt,
i);
742 double w = integral_pt()->weight(ipt);
746 double J = shape_basis_test_local_at_knot(ipt,
764 double interpolated_div_du_dt_dx = 0.0;
767 double interpolated_div_q_ds = 0.0;
769 double interpolated_p = 0.0;
772 for (
unsigned l = 0; l < n_node; l++)
775 for (
unsigned i = 0;
i < DIM;
i++)
777 interpolated_x[
i] += nodal_position(l,
i) * psi(l);
779 interpolated_d2u_dt2[
i] += this->d2u_dt2(l,
i) * u_basis(l);
782 const double u_value = this->raw_nodal_value(l, u_index(
i));
783 interpolated_u[
i] += u_value * u_basis(l);
786 for (
unsigned j = 0; j < DIM; j++)
788 interpolated_du_dx(
i, j) += u_value * du_basis_dx(l, j);
792 interpolated_div_du_dt_dx += this->du_dt(l,
i) * du_basis_dx(l,
i);
798 for (
unsigned i = 0;
i < DIM;
i++)
801 for (
unsigned l = 0; l < n_q_basis_edge; l++)
803 interpolated_q[
i] += q_edge(l) * q_basis(l,
i);
804 interpolated_dq_dt[
i] += dq_edge_dt(l) * q_basis(l,
i);
807 for (
unsigned l = n_q_basis_edge; l < n_q_basis; l++)
809 interpolated_q[
i] += q_internal(l - n_q_basis_edge) * q_basis(l,
i);
810 interpolated_dq_dt[
i] +=
811 dq_internal_dt(l - n_q_basis_edge) * q_basis(l,
i);
816 for (
unsigned l = 0; l < n_p_basis; l++)
818 interpolated_p += p_value(l) * p_basis(l);
823 for (
unsigned l = 0; l < n_q_basis_edge; l++)
825 interpolated_div_q_ds += q_edge(l) * div_q_basis_ds(l);
827 for (
unsigned l = n_q_basis_edge; l < n_q_basis; l++)
829 interpolated_div_q_ds +=
830 q_internal(l - n_q_basis_edge) * div_q_basis_ds(l);
834 this->force_solid(time, interpolated_x, f_solid);
837 this->force_fluid(time, interpolated_x, f_fluid);
840 this->mass_source(time, interpolated_x, mass_source_local);
847 for (
unsigned l = 0; l < n_node; l++)
849 for (
unsigned a = 0; a < DIM; a++)
851 local_eqn = this->nodal_local_eqn(l, u_index(a));
855 residuals[local_eqn] +=
856 (lambda_sq * (interpolated_d2u_dt2[a] +
857 rho_f_over_rho * interpolated_dq_dt[a]) -
862 for (
unsigned b = 0; b < DIM; b++)
866 residuals[local_eqn] -=
867 alpha * interpolated_p * du_test_dx(l, b) *
W;
870 for (
unsigned c = 0; c < DIM; c++)
872 for (
unsigned d = 0; d < DIM; d++)
875 residuals[local_eqn] += this->
E(a, b, c, d) *
876 interpolated_du_dx(c, d) *
877 du_test_dx(l, b) *
W;
885 for (
unsigned l2 = 0; l2 < n_node; l2++)
887 for (
unsigned c = 0; c < DIM; c++)
889 local_unknown = this->nodal_local_eqn(l2, u_index(c));
890 if (local_unknown >= 0)
894 jacobian(local_eqn, local_unknown) +=
896 this->node_pt(l2)->time_stepper_pt()->weight(2, 0) *
897 u_basis(l2) * u_test(l) *
W;
900 for (
unsigned b = 0; b < DIM; b++)
902 for (
unsigned d = 0; d < DIM; d++)
904 jacobian(local_eqn, local_unknown) +=
905 this->
E(a, b, c, d) * du_basis_dx(l2, d) *
906 du_test_dx(l, b) *
W;
914 for (
unsigned l2 = 0; l2 < n_q_basis; l2++)
916 TimeStepper* timestepper_pt = 0;
918 if (l2 < n_q_basis_edge)
920 local_unknown = q_edge_local_eqn(l2);
922 this->node_pt(q_edge_node_number(l2))->time_stepper_pt();
926 local_unknown = q_internal_local_eqn(l2 - n_q_basis_edge);
927 timestepper_pt = this->internal_data_pt(q_internal_index())
931 if (local_unknown >= 0)
933 jacobian(local_eqn, local_unknown) +=
934 lambda_sq * rho_f_over_rho * timestepper_pt->weight(1, 0) *
935 q_basis(l2, a) * u_test(l) *
W;
940 for (
unsigned l2 = 0; l2 < n_p_basis; l2++)
942 local_unknown = p_local_eqn(l2);
943 if (local_unknown >= 0)
945 jacobian(local_eqn, local_unknown) -=
946 alpha * p_basis(l2) * du_test_dx(l, a) *
W;
957 for (
unsigned l = 0; l < n_q_basis; l++)
959 if (l < n_q_basis_edge)
961 local_eqn = q_edge_local_eqn(l);
965 local_eqn = q_internal_local_eqn(l - n_q_basis_edge);
971 for (
unsigned i = 0;
i < DIM;
i++)
973 residuals[local_eqn] +=
974 (k_inv * interpolated_q[
i] - rho_f_over_rho * f_fluid[
i] +
975 rho_f_over_rho * lambda_sq *
976 (interpolated_d2u_dt2[
i] +
977 (1.0 / porosity) * interpolated_dq_dt[
i])) *
978 q_test(l,
i) * w * J;
982 residuals[local_eqn] -= (interpolated_p * div_q_test_ds(l)) * w;
988 for (
unsigned l2 = 0; l2 < n_node; l2++)
990 for (
unsigned c = 0; c < DIM; c++)
992 local_unknown = this->nodal_local_eqn(l2, u_index(c));
993 if (local_unknown >= 0)
995 jacobian(local_eqn, local_unknown) +=
996 rho_f_over_rho * lambda_sq *
997 this->node_pt(l2)->time_stepper_pt()->weight(2, 0) *
998 u_basis(l2) * q_test(l, c) *
W;
1004 for (
unsigned l2 = 0; l2 < n_q_basis; l2++)
1006 TimeStepper* timestepper_pt = 0;
1008 if (l2 < n_q_basis_edge)
1010 local_unknown = q_edge_local_eqn(l2);
1012 this->node_pt(q_edge_node_number(l2))->time_stepper_pt();
1016 local_unknown = q_internal_local_eqn(l2 - n_q_basis_edge);
1018 this->internal_data_pt(q_internal_index())->time_stepper_pt();
1021 if (local_unknown >= 0)
1023 for (
unsigned c = 0; c < DIM; c++)
1025 jacobian(local_eqn, local_unknown) +=
1026 q_basis(l2, c) * q_test(l, c) *
1027 (k_inv + rho_f_over_rho * lambda_sq *
1028 timestepper_pt->weight(1, 0) / porosity) *
1035 for (
unsigned l2 = 0; l2 < n_p_basis; l2++)
1037 local_unknown = p_local_eqn(l2);
1040 jacobian(local_eqn, local_unknown) -=
1041 p_basis(l2) * div_q_test_ds(l) * w;
1048 for (
unsigned l = 0; l < n_p_basis; l++)
1051 local_eqn = p_local_eqn(l);
1057 residuals[local_eqn] +=
1058 alpha * interpolated_div_du_dt_dx * p_test(l) * w * J;
1061 residuals[local_eqn] += interpolated_div_q_ds * p_test(l) * w;
1063 residuals[local_eqn] -= mass_source_local * p_test(l) * w * J;
1069 for (
unsigned l2 = 0; l2 < n_node; l2++)
1071 for (
unsigned c = 0; c < DIM; c++)
1073 local_unknown = this->nodal_local_eqn(l2, u_index(c));
1075 if (local_unknown >= 0)
1077 jacobian(local_eqn, local_unknown) +=
1078 alpha * this->node_pt(l2)->time_stepper_pt()->weight(1, 0) *
1079 du_basis_dx(l2, c) * p_test(l) *
W;
1085 for (
unsigned l2 = 0; l2 < n_q_basis; l2++)
1087 if (l2 < n_q_basis_edge)
1089 local_unknown = q_edge_local_eqn(l2);
1093 local_unknown = q_internal_local_eqn(l2 - n_q_basis_edge);
1096 if (local_unknown >= 0)
1098 jacobian(local_eqn, local_unknown) +=
1099 p_test(l) * div_q_basis_ds(l2) * w;
1109 template class PoroelasticityEquations<2>;
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
unsigned long nrow() const
Return the number of rows of the matrix.
unsigned long ncol() const
Return the number of columns of the matrix.
void(* SteadyExactSolutionFctPt)(const Vector< double > &, Vector< double > &)
Function pointer for function that computes vector-valued steady "exact solution" as .
void(* UnsteadyExactSolutionFctPt)(const double &, const Vector< double > &, Vector< double > &)
Function pointer for function that computes Vector-valued time-dependent function as .
An OomphLibError object which should be thrown when an run-time error is encountered....
void output_fct(std::ostream &outfile, const unsigned &nplot, FiniteElement::SteadyExactSolutionFctPt exact_soln_pt)
Output FE representation of exact soln: x,y,u1,u2,div_q,p at Nplot^DIM plot points.
static double Default_porosity_value
Static default value for the porosity.
double transform_basis(const Vector< double > &s, const Shape &q_basis_local, Shape &psi, DShape &dpsi, Shape &q_basis) const
Performs a div-conserving transformation of the vector basis functions from the reference element to ...
static double Default_density_ratio_value
Static default value for the density ratio.
void get_stress(const Vector< double > &s, DenseMatrix< double > &sigma) const
Return the Cauchy stress tensor, as calculated from the elasticity tensor at specified local coordina...
virtual void fill_in_generic_residual_contribution(Vector< double > &residuals, DenseMatrix< double > &jacobian, bool flag)
Fill in residuals and, if flag==true, jacobian.
static double Default_lambda_sq_value
Static default value for timescale ratio (1.0 – for natural scaling)
static double Default_alpha_value
Static default value for alpha.
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 ...
static double Default_k_inv_value
Static default value for 1/k.
void output(std::ostream &outfile)
Output with default number of plot points.
void get_strain(const Vector< double > &s, DenseMatrix< double > &strain) const
Return the strain tensor.
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
void shape(const double &s, double *Psi)
Definition for 1D Lagrange shape functions. The value of all the shape functions at the local coordin...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...