29 #include "../generic/shape.h"
30 #include "../generic/timesteppers.h"
39 template<
unsigned DIM>
44 const unsigned n_flux = nflux();
52 for (
unsigned p = 0; p < n_flux; p++)
55 const double old_var = u_local[p];
57 u_local[p] += fd_step;
59 flux(u_local, F_plus);
64 u_local[p] -= fd_step;
66 flux(u_local, F_minus);
69 for (
unsigned r = 0; r < n_flux; r++)
71 for (
unsigned j = 0; j < DIM; j++)
73 df_du(r, j, p) = (F_plus(r, j) - F_minus(r, j)) / (2.0 * fd_step);
88 template<
unsigned DIM>
97 const unsigned n_flux = this->nflux();
99 const unsigned n_node = this->nnode();
101 Shape psi(n_node), test(n_node);
102 DShape dpsidx(n_node, DIM), dtestdx(n_node, DIM);
105 unsigned u_nodal_index[n_flux];
106 for (
unsigned i = 0;
i < n_flux;
i++)
108 u_nodal_index[
i] = this->u_index_flux_transport(
i);
112 unsigned n_intpt = this->integral_pt()->nweight();
115 int local_eqn = 0, local_unknown = 0;
118 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
121 double J = this->dshape_and_dtest_eulerian_at_knot_flux_transport(
122 ipt, psi, dpsidx, test, dtestdx);
125 double W = this->integral_pt()->weight(ipt) * J;
132 for (
unsigned l = 0; l < n_node; l++)
135 const double psi_ = psi(l);
136 for (
unsigned i = 0;
i < n_flux;
i++)
139 interpolated_u[
i] += this->nodal_value(l, u_nodal_index[
i]) * psi_;
140 interpolated_dudt[
i] += this->du_dt_flux_transport(l,
i) * psi_;
146 this->flux(interpolated_u,
F);
149 if ((flag) && (flag != 3))
151 this->dflux_du(interpolated_u, dF_du);
155 for (
unsigned l = 0; l < n_node; l++)
158 for (
unsigned i = 0;
i < n_flux;
i++)
161 local_eqn = this->nodal_local_eqn(l,
i);
167 residuals[local_eqn] -= interpolated_dudt[
i] * test(l) *
W;
171 double flux_dot = 0.0;
172 for (
unsigned k = 0; k < DIM; k++)
174 flux_dot +=
F(
i, k) * dtestdx(l, k);
178 residuals[local_eqn] += flux_dot *
W;
187 for (
unsigned l2 = 0; l2 < n_node; l2++)
190 for (
unsigned i2 = 0; i2 < n_flux; i2++)
193 local_unknown = this->nodal_local_eqn(l2, i2);
195 if (local_unknown >= 0)
200 jacobian(local_eqn, local_unknown) -=
201 node_pt(l2)->time_stepper_pt()->weight(1, 0) *
202 psi(l2) * test(l) *
W;
208 mass_matrix(local_eqn, local_unknown) +=
209 psi(l2) * test(l) *
W;
214 double dflux_dot = 0.0;
215 for (
unsigned k = 0; k < DIM; k++)
217 dflux_dot += dF_du(
i, k, i2) * dtestdx(l, k);
219 jacobian(local_eqn, local_unknown) +=
220 dflux_dot * psi(l2) *
W;
229 for (
unsigned l2 = 0; l2 < n_node; l2++)
231 local_unknown = this->nodal_local_eqn(l2,
i);
232 if (local_unknown >= 0)
234 mass_matrix(local_eqn, local_unknown) +=
235 psi(l2) * test(l) *
W;
249 template<
unsigned DIM>
254 const unsigned n_node = this->nnode();
263 for (
unsigned n = 0; n < n_node; n++)
265 const double psi_ = psi[n];
266 u += this->nodal_value(n, u_index_flux_transport(
i)) * psi_;
275 template<
unsigned DIM>
277 const unsigned& n,
const unsigned&
i)
const
280 TimeStepper* time_stepper_pt = this->node_pt(n)->time_stepper_pt();
289 const unsigned u_nodal_index = this->u_index_flux_transport(
i);
292 const unsigned n_time = time_stepper_pt->
ntstorage();
294 for (
unsigned t = 0;
t < n_time;
t++)
297 time_stepper_pt->
weight(1,
t) * nodal_value(
t, n, u_nodal_index);
307 template<
unsigned DIM>
309 double*& average_value)
312 const unsigned n_flux = this->nflux();
314 if (average_value == 0)
316 average_value =
new double[n_flux + 1];
320 for (
unsigned i = 0;
i < n_flux + 1;
i++)
322 average_value[
i] = 0.0;
326 const unsigned n_node = this->nnode();
329 DShape dpsidx(n_node, DIM);
332 unsigned u_nodal_index[n_flux];
333 for (
unsigned i = 0;
i < n_flux;
i++)
335 u_nodal_index[
i] = this->u_index_flux_transport(
i);
339 unsigned n_intpt = this->integral_pt()->nweight();
342 for (
unsigned ipt = 0; ipt < n_intpt; ipt++)
345 double J = this->dshape_eulerian_at_knot(ipt, psi, dpsidx);
348 double W = this->integral_pt()->weight(ipt) * J;
354 for (
unsigned l = 0; l < n_node; l++)
357 const double psi_ = psi(l);
358 for (
unsigned i = 0;
i < n_flux;
i++)
361 interpolated_u[
i] += this->nodal_value(l, u_nodal_index[
i]) * psi_;
365 average_value[n_flux] +=
W;
367 for (
unsigned i = 0;
i < n_flux;
i++)
369 average_value[
i] += interpolated_u[
i] *
W;
374 for (
unsigned i = 0;
i < n_flux;
i++)
376 average_value[
i] /= average_value[n_flux];
384 template<
unsigned DIM>
386 const unsigned& nplot)
389 const unsigned n_flux = this->nflux();
395 outfile << tecplot_zone_string(nplot);
398 unsigned num_plot_points = nplot_points(nplot);
399 for (
unsigned iplot = 0; iplot < num_plot_points; iplot++)
402 get_s_plot(iplot, nplot,
s);
405 for (
unsigned i = 0;
i < DIM;
i++)
407 outfile << interpolated_x(
s,
i) <<
" ";
411 for (
unsigned i = 0;
i < n_flux;
i++)
413 outfile << interpolated_u_flux_transport(
s,
i) <<
" ";
416 outfile << std::endl;
418 outfile << std::endl;
421 write_tecplot_zone_footer(outfile, nplot);
A Class for the derivatives of shape functions The class design is essentially the same as Shape,...
Base class for the flux transport equations templated by the dimension DIM. The equations that are so...
virtual void fill_in_generic_residual_contribution_flux_transport(Vector< double > &residuals, DenseMatrix< double > &jacobian, DenseMatrix< double > &mass_matrix, unsigned flag)
Compute the residuals for the Navier–Stokes equations; flag=1(or 0): do (or don't) compute the Jacobi...
void calculate_element_averages(double *&average_values)
Compute the average values of the fluxes.
virtual void dflux_du(const Vector< double > &u, RankThreeTensor< double > &df_du)
Return the flux derivatives as a funciton of the unknowns Default finite-different implementation.
double interpolated_u_flux_transport(const Vector< double > &s, const unsigned &i)
Return the i-th unknown at the local coordinate s.
double du_dt_flux_transport(const unsigned &n, const unsigned &i) const
i-th component of du/dt at local node n. Uses suitably interpolated value for hanging nodes.
void output(std::ostream &outfile)
Output the element data — typically the values at the nodes in a format suitable for post-processing.
static double Default_fd_jacobian_step
Double used for the default finite difference step in elemental jacobian calculations.
////////////////////////////////////////////////////////////////// //////////////////////////////////...
A Class for shape functions. In simple cases, the shape functions have only one index that can be tho...
////////////////////////////////////////////////////////////////////// //////////////////////////////...
unsigned ntstorage() const
Return the number of doubles required to represent history (one for steady)
virtual double weight(const unsigned &i, const unsigned &j) const
Access function for j-th weight for the i-th derivative.
bool is_steady() const
Flag to indicate if a timestepper has been made steady (possibly temporarily to switch off time-depen...
void shape(const double &s, double *Psi)
Definition for 1D Lagrange shape functions. The value of all the shape functions at the local coordin...
//////////////////////////////////////////////////////////////////// ////////////////////////////////...