Loading [MathJax]/extensions/tex2jax.js
libMesh
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
naviersystem.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 // Example includes
19 #include "naviersystem.h"
20 
21 // libMesh includes
22 #include "libmesh/getpot.h"
23 #include "libmesh/dirichlet_boundaries.h"
24 #include "libmesh/dof_map.h"
25 #include "libmesh/fe_base.h"
26 #include "libmesh/fe_interface.h"
27 #include "libmesh/fem_context.h"
28 #include "libmesh/mesh.h"
29 #include "libmesh/quadrature.h"
30 #include "libmesh/string_to_enum.h"
31 #include "libmesh/zero_function.h"
32 #include "libmesh/elem.h"
33 
34 // C++ includes
35 #include <array>
36 #include <functional> // std::reference_wrapper
37 #include <memory>
38 
39 // Bring in everything from the libMesh namespace
40 using namespace libMesh;
41 
42 
43 // Boundary conditions for the 3D test case
44 class BdyFunction : public FunctionBase<Number>
45 {
46 public:
47  BdyFunction (unsigned int u_var,
48  unsigned int v_var,
49  unsigned int w_var,
50  Real Reynolds)
51  : _u_var(u_var), _v_var(v_var), _w_var(w_var), _Re(Reynolds)
52  { this->_initialized = true; }
53 
54  virtual Number operator() (const Point &, const Real = 0)
55  { libmesh_not_implemented(); }
56 
57  virtual void operator() (const Point & p,
58  const Real,
59  DenseVector<Number> & output)
60  {
61  output.zero();
62  const Real x=p(0), y=p(1), z=p(2);
63  output(_u_var) = (_Re+1)*(y*y + z*z);
64  output(_v_var) = (_Re+1)*(x*x + z*z);
65  output(_w_var) = (_Re+1)*(x*x + y*y);
66  }
67 
68  virtual std::unique_ptr<FunctionBase<Number>> clone() const
69  { return std::make_unique<BdyFunction>(_u_var, _v_var, _w_var, _Re); }
70 
71 private:
72  const unsigned int _u_var, _v_var, _w_var;
73  const Real _Re;
74 };
75 
76 
78 {
79  const unsigned int dim = this->get_mesh().mesh_dimension();
80 
81  // Check the input file for Reynolds number, application type,
82  // approximation type
83  GetPot infile("navier.in");
84  Reynolds = infile("Reynolds", 1.);
85  application = infile("application", 0);
86  unsigned int pressure_p = infile("pressure_p", 1);
87  std::string fe_family = infile("fe_family", std::string("LAGRANGE"));
88 
89  // LBB needs better-than-quadratic velocities for better-than-linear
90  // pressures, and libMesh needs non-Lagrange elements for
91  // better-than-quadratic velocities.
92  libmesh_assert((pressure_p == 1) || (fe_family != "LAGRANGE"));
93 
94  FEFamily fefamily = Utility::string_to_enum<FEFamily>(fe_family);
95 
96  // Add the velocity components "u" & "v". They
97  // will be approximated using second-order approximation.
98  u_var = this->add_variable ("u", static_cast<Order>(pressure_p+1),
99  fefamily);
100  v_var = this->add_variable ("v",
101  static_cast<Order>(pressure_p+1),
102  fefamily);
103 
104  if (dim == 3)
105  w_var = this->add_variable ("w",
106  static_cast<Order>(pressure_p+1),
107  fefamily);
108  else
109  w_var = u_var;
110 
111  // Add the pressure variable "p". This will
112  // be approximated with a first-order basis,
113  // providing an LBB-stable pressure-velocity pair.
114  p_var = this->add_variable ("p",
115  static_cast<Order>(pressure_p),
116  fefamily);
117 
118  // Tell the system to march velocity forward in time, but
119  // leave p as a constraint only
120  this->time_evolving(u_var, 1);
121  this->time_evolving(v_var, 1);
122  if (dim == 3)
123  this->time_evolving(w_var, 1);
124 
125  // Useful debugging options
126  // Set verify_analytic_jacobians to 1e-6 to use
127  this->verify_analytic_jacobians = infile("verify_analytic_jacobians", 0.);
128  this->print_jacobians = infile("print_jacobians", false);
129  this->print_element_jacobians = infile("print_element_jacobians", false);
130 
131  // Set Dirichlet boundary conditions
132 #ifdef LIBMESH_ENABLE_DIRICHLET
133  const boundary_id_type top_id = (dim==3) ? 5 : 2;
134 
135  std::set<boundary_id_type> top_bdys { top_id };
136 
137  const boundary_id_type all_ids[6] = {0, 1, 2, 3, 4, 5};
138  std::set<boundary_id_type> all_bdys(all_ids, all_ids+(dim*2));
139 
140  std::set<boundary_id_type> nontop_bdys = all_bdys;
141  nontop_bdys.erase(top_id);
142 
143  std::vector<unsigned int> uvw {u_var, v_var, w_var};
144 
146  ConstFunction<Number> one(1);
147  // For lid-driven cavity, set u=1,v=w=0 on the lid and u=v=w=0 elsewhere
148  if (application == 0)
149  {
150  this->get_dof_map().add_dirichlet_boundary
151  (DirichletBoundary (top_bdys, {u_var}, &one));
152  this->get_dof_map().add_dirichlet_boundary
153  (DirichletBoundary (top_bdys, {v_var,w_var}, &zero));
154  this->get_dof_map().add_dirichlet_boundary
155  (DirichletBoundary (nontop_bdys, uvw, &zero));
156  }
157  // For forcing with zero wall velocity, set homogeneous Dirichlet BCs
158  else if (application == 1)
159  {
160  this->get_dof_map().add_dirichlet_boundary
161  (DirichletBoundary (all_bdys, uvw, &zero));
162  }
163  // For 3D test case with quadratic velocity field, set that field on walls
164  else if (application == 2)
165  {
166  BdyFunction bdy(u_var, v_var, w_var, Reynolds);
167  this->get_dof_map().add_dirichlet_boundary
168  (DirichletBoundary (all_bdys, uvw, &bdy));
169  }
170 #endif // LIBMESH_ENABLE_DIRICHLET
171 
172  // Do the parent's initialization after variables and boundary constraints are defined
174 }
175 
176 
177 
179 {
180  FEMContext & c = cast_ref<FEMContext &>(context);
181 
182  FEBase * u_elem_fe;
183  FEBase * p_elem_fe;
184  FEBase * u_side_fe;
185 
186  c.get_element_fe(u_var, u_elem_fe);
187  c.get_element_fe(p_var, p_elem_fe);
188  c.get_side_fe(u_var, u_side_fe);
189 
190  // We should prerequest all the data
191  // we will need to build the linear system.
192  u_elem_fe->get_JxW();
193  u_elem_fe->get_phi();
194  u_elem_fe->get_dphi();
195  u_elem_fe->get_xyz();
196 
197  p_elem_fe->get_phi();
198 
199  u_side_fe->get_JxW();
200  u_side_fe->get_phi();
201  u_side_fe->get_xyz();
202 
203  // And tell the context what data we *don't* need
204  FEBase * p_side_fe;
205  c.get_side_fe(p_var, p_side_fe);
206  p_side_fe->get_nothing();
207 }
208 
209 
210 bool NavierSystem::element_time_derivative (bool request_jacobian,
211  DiffContext & context)
212 {
213  FEMContext & c = cast_ref<FEMContext &>(context);
214 
215  FEBase * u_elem_fe;
216  FEBase * p_elem_fe;
217 
218  c.get_element_fe(u_var, u_elem_fe);
219  c.get_element_fe(p_var, p_elem_fe);
220 
221  // First we get some references to cell-specific data that
222  // will be used to assemble the linear system.
223 
224  // Element Jacobian * quadrature weights for interior integration
225  const std::vector<Real> & JxW = u_elem_fe->get_JxW();
226 
227  // The velocity shape functions at interior quadrature points.
228  const std::vector<std::vector<Real>> & phi = u_elem_fe->get_phi();
229 
230  // The velocity shape function gradients at interior
231  // quadrature points.
232  const std::vector<std::vector<RealGradient>> & dphi = u_elem_fe->get_dphi();
233 
234  // The pressure shape functions at interior
235  // quadrature points.
236  const std::vector<std::vector<Real>> & psi = p_elem_fe->get_phi();
237 
238  // Physical location of the quadrature points
239  const std::vector<Point> & qpoint = u_elem_fe->get_xyz();
240 
241  // The number of local degrees of freedom in each variable
242  const unsigned int n_p_dofs = c.n_dof_indices(p_var);
243  const unsigned int n_u_dofs = c.n_dof_indices(u_var);
244  libmesh_assert_equal_to (n_u_dofs, c.n_dof_indices(v_var));
245 
246  const unsigned int dim = this->get_mesh().mesh_dimension();
247 
248  // Get DenseSubMatrix references for velocity-velocity coupling
249  // Kuu, Kuv, Kuw
250  // Kvu, Kvv, Kvw
251  // Kwu, Kwv, Kww
252  std::reference_wrapper<DenseSubMatrix<Number>> K[3][3] =
253  {
254  {c.get_elem_jacobian(u_var, u_var), c.get_elem_jacobian(u_var, v_var), c.get_elem_jacobian(u_var, w_var)},
255  {c.get_elem_jacobian(v_var, u_var), c.get_elem_jacobian(v_var, v_var), c.get_elem_jacobian(v_var, w_var)},
256  {c.get_elem_jacobian(w_var, u_var), c.get_elem_jacobian(w_var, v_var), c.get_elem_jacobian(w_var, w_var)}
257  };
258 
259  // Get DenseSubMatrix references for velocity-pressure coupling
260  // Kup
261  // Kvp
262  // Kwp
263  std::reference_wrapper<DenseSubMatrix<Number>> B[3] =
264  {
265  c.get_elem_jacobian(u_var, p_var),
266  c.get_elem_jacobian(v_var, p_var),
267  c.get_elem_jacobian(w_var, p_var)
268  };
269 
270  // Get rhs DenseSubVector references
271  // Fu
272  // Fv
273  // Fw
274  std::reference_wrapper<DenseSubVector<Number>> F[3] =
275  {
276  c.get_elem_residual(u_var),
277  c.get_elem_residual(v_var),
278  c.get_elem_residual(w_var)
279  };
280 
281  // Now we will build the element Jacobian and residual.
282  // Constructing the residual requires the solution and its
283  // gradient from the previous timestep. This must be
284  // calculated at each quadrature point by summing the
285  // solution degree-of-freedom values by the appropriate
286  // weight functions.
287  unsigned int n_qpoints = c.get_element_qrule().n_points();
288 
289  // Pressure at current Newton iterate
290  Number p;
291 
292  // Velocity at current Newton iterate
294 
295  // Store (grad_u, grad_v, grad_w) at current Newton iterate
296  Gradient grad_uvw[3];
297 
298  for (unsigned int qp=0; qp != n_qpoints; qp++)
299  {
300  // Compute the solution & its gradient at the current Newton iterate
301  c.interior_value(p_var, qp, p);
302  c.interior_value(u_var, qp, U(0));
303  c.interior_value(v_var, qp, U(1));
304  c.interior_value(w_var, qp, U(2));
305  c.interior_gradient(u_var, qp, grad_uvw[0]);
306  c.interior_gradient(v_var, qp, grad_uvw[1]);
307  c.interior_gradient(w_var, qp, grad_uvw[2]);
308 
309  // Value of the forcing function at this quadrature point
310  Point f = this->forcing(qpoint[qp]);
311 
312  // First, an i-loop over the velocity degrees of freedom.
313  // We know that n_u_dofs == n_v_dofs so we can compute contributions
314  // for both at the same time.
315  for (unsigned int i=0; i != n_u_dofs; i++)
316  {
317  for (unsigned int d = 0; d < dim; ++d)
318  F[d](i) += JxW[qp] *
319  (-Reynolds*(U*grad_uvw[d])*phi[i][qp] + // convection term
320  p*dphi[i][qp](d) - // pressure term
321  (grad_uvw[d]*dphi[i][qp]) + // diffusion term
322  f(d)*phi[i][qp]); // forcing function
323 
324  // Note that the Fp block is identically zero unless we are using
325  // some kind of artificial compressibility scheme...
326  if (request_jacobian && c.elem_solution_derivative)
327  {
328  libmesh_assert_equal_to (c.elem_solution_derivative, 1.0);
329 
330  // Matrix contributions for the uu and vv couplings.
331  for (unsigned int j=0; j != n_u_dofs; j++)
332  for (unsigned int k = 0; k < dim; ++k)
333  for (unsigned int l = 0; l < dim; ++l)
334  {
335  // "Diagonal" contributions
336  if (k == l)
337  K[k][k](i,j) += JxW[qp] *
338  (-Reynolds*(U*dphi[j][qp])*phi[i][qp] - // convection term
339  (dphi[i][qp]*dphi[j][qp])); // diffusion term
340 
341  // Newton terms
342  K[k][l](i,j) += JxW[qp] * -Reynolds*grad_uvw[k](l)*phi[i][qp]*phi[j][qp];
343  }
344 
345  // Matrix contributions for the velocity-pressure couplings.
346  for (unsigned int j=0; j != n_p_dofs; j++)
347  for (unsigned int k = 0; k < dim; ++k)
348  B[k](i,j) += JxW[qp]*psi[j][qp]*dphi[i][qp](k);
349  }
350  }
351  } // end of the quadrature point qp-loop
352 
353  return request_jacobian;
354 }
355 
356 
357 
358 bool NavierSystem::element_constraint (bool request_jacobian,
359  DiffContext & context)
360 {
361  FEMContext & c = cast_ref<FEMContext &>(context);
362 
363  FEBase * u_elem_fe;
364  FEBase * p_elem_fe;
365 
366  c.get_element_fe(u_var, u_elem_fe);
367  c.get_element_fe(p_var, p_elem_fe);
368 
369  // Here we define some references to cell-specific data that
370  // will be used to assemble the linear system.
371 
372  // Element Jacobian * quadrature weight for interior integration
373  const std::vector<Real> & JxW = u_elem_fe->get_JxW();
374 
375  // The velocity shape function gradients at interior
376  // quadrature points.
377  const std::vector<std::vector<RealGradient>> & dphi = u_elem_fe->get_dphi();
378 
379  // The pressure shape functions at interior
380  // quadrature points.
381  const std::vector<std::vector<Real>> & psi = p_elem_fe->get_phi();
382 
383  // The number of local degrees of freedom in each variable
384  const unsigned int n_u_dofs = c.n_dof_indices(u_var);
385  const unsigned int n_p_dofs = c.n_dof_indices(p_var);
386 
387  // The subvectors and submatrices we need to fill:
388  const unsigned int dim = this->get_mesh().mesh_dimension();
389 
390  // Get DenseSubMatrix references for velocity-pressure coupling
391  // Kpu Kpv Kpw
392  std::reference_wrapper<DenseSubMatrix<Number>> B[3] =
393  {
394  c.get_elem_jacobian(p_var, u_var),
395  c.get_elem_jacobian(p_var, v_var),
396  c.get_elem_jacobian(p_var, w_var)
397  };
398 
399  // Get reference to pressure equation elem residual
401 
402  // Add the constraint given by the continuity equation
403  unsigned int n_qpoints = c.get_element_qrule().n_points();
404 
405  // Store (grad_u, grad_v, grad_w) at current Newton iterate
406  Gradient grad_uvw[3];
407 
408  for (unsigned int qp=0; qp != n_qpoints; qp++)
409  {
410  // Compute the velocity gradient at the old Newton iterate
411  c.interior_gradient(u_var, qp, grad_uvw[0]);
412  c.interior_gradient(v_var, qp, grad_uvw[1]);
413  c.interior_gradient(w_var, qp, grad_uvw[2]);
414 
415  // Now a loop over the pressure degrees of freedom. This
416  // computes the contributions of the continuity equation.
417  for (unsigned int i=0; i != n_p_dofs; i++)
418  {
419  for (unsigned int k = 0; k < dim; ++k)
420  Fp(i) += JxW[qp] * psi[i][qp] * grad_uvw[k](k);
421 
422  if (request_jacobian && c.get_elem_solution_derivative())
423  {
424  libmesh_assert_equal_to (c.get_elem_solution_derivative(), 1.0);
425 
426  for (unsigned int j=0; j != n_u_dofs; j++)
427  for (unsigned int k = 0; k < dim; ++k)
428  B[k](i,j) += JxW[qp]*psi[i][qp]*dphi[j][qp](k);
429  }
430  }
431  } // end of the quadrature point qp-loop
432 
433  return request_jacobian;
434 }
435 
436 
437 
438 bool NavierSystem::side_constraint (bool request_jacobian,
439  DiffContext & context)
440 {
441  FEMContext & c = cast_ref<FEMContext &>(context);
442 
443  FEBase * p_elem_fe;
444 
445  c.get_element_fe(p_var, p_elem_fe);
446 
447  // Pin p = 0 at the origin
448  const Point zero(0., 0.);
449 
450  if (c.get_elem().contains_point(zero))
451  {
452  // The pressure penalty value. \f$ \frac{1}{\epsilon} \f$
453  const Real penalty = 1.e9;
454 
455  DenseSubMatrix<Number> & Kpp = c.get_elem_jacobian(p_var, p_var);
457  const unsigned int n_p_dofs = c.n_dof_indices(p_var);
458 
459  Number p;
460  c.point_value(p_var, zero, p);
461 
462  Number p_value = 0.;
463 
464  unsigned int dim = get_mesh().mesh_dimension();
465  FEType fe_type = p_elem_fe->get_fe_type();
466  Point p_master = FEMap::inverse_map(dim, &c.get_elem(), zero);
467 
468  std::vector<Real> point_phi(n_p_dofs);
469  for (unsigned int i=0; i != n_p_dofs; i++)
470  {
471  point_phi[i] = FEInterface::shape(fe_type, &c.get_elem(), i, p_master);
472  }
473 
474  for (unsigned int i=0; i != n_p_dofs; i++)
475  {
476  Fp(i) += penalty * (p - p_value) * point_phi[i];
477  if (request_jacobian && c.get_elem_solution_derivative())
478  {
479  libmesh_assert_equal_to (c.get_elem_solution_derivative(), 1.0);
480 
481  for (unsigned int j=0; j != n_p_dofs; j++)
482  Kpp(i,j) += penalty * point_phi[i] * point_phi[j];
483  }
484  }
485  }
486 
487  return request_jacobian;
488 }
489 
490 
491 // We override the default mass_residual function,
492 // because in the non-dimensionalized Navier-Stokes equations
493 // the time derivative of velocity has a Reynolds number coefficient.
494 // Alternatively we could divide the whole equation by
495 // Reynolds number (or choose a more complicated non-dimensionalization
496 // of time), but this gives us an opportunity to demonstrate overriding
497 // FEMSystem::mass_residual()
498 bool NavierSystem::mass_residual (bool request_jacobian,
499  DiffContext & context)
500 {
501  FEMContext & c = cast_ref<FEMContext &>(context);
502 
503  FEBase * u_elem_fe;
504 
505  c.get_element_fe(u_var, u_elem_fe);
506 
507  // The subvectors and submatrices we need to fill:
508  const unsigned int dim = this->get_mesh().mesh_dimension();
509 
510  // Element Jacobian * quadrature weight for interior integration
511  const std::vector<Real> & JxW = u_elem_fe->get_JxW();
512 
513  // The velocity shape functions at interior quadrature points.
514  const std::vector<std::vector<Real>> & phi = u_elem_fe->get_phi();
515 
516  // Get rhs DenseSubVector references
517  std::reference_wrapper<DenseSubVector<Number>> F[3] =
518  {
519  c.get_elem_residual(u_var),
520  c.get_elem_residual(v_var),
521  c.get_elem_residual(w_var)
522  };
523 
524  // Get references to stiffness matrix diagonal blocks
525  std::reference_wrapper<DenseSubMatrix<Number>> Kdiag[3] =
526  {
527  c.get_elem_jacobian(u_var, u_var),
528  c.get_elem_jacobian(v_var, v_var),
529  c.get_elem_jacobian(w_var, w_var)
530  };
531 
532  // The number of local degrees of freedom in velocity
533  const unsigned int n_u_dofs = c.n_dof_indices(u_var);
534 
535  unsigned int n_qpoints = c.get_element_qrule().n_points();
536 
537  // Stores JxW * Reynolds * du/dt at current Newton iterate
538  std::array<Number, 3> accel;
539 
540  for (unsigned int qp = 0; qp != n_qpoints; ++qp)
541  {
542  // Compute time derivatives
543  c.interior_rate(u_var, qp, accel[0]);
544  c.interior_rate(v_var, qp, accel[1]);
545  c.interior_rate(w_var, qp, accel[2]);
546 
547  // We pull as many calculations as possible outside of loops
548  Number JxWxRe = JxW[qp] * Reynolds;
549  for (unsigned int k = 0; k < dim; ++k)
550  accel[k] *= JxWxRe;
551 
552  for (unsigned int i = 0; i != n_u_dofs; ++i)
553  {
554  for (unsigned int k = 0; k < dim; ++k)
555  F[k](i) -= accel[k] * phi[i][qp];
556 
557  if (request_jacobian && c.get_elem_solution_derivative())
558  {
559  libmesh_assert_equal_to (c.get_elem_solution_derivative(), 1.0);
560 
561  Number JxWxRexPhiI = JxWxRe * phi[i][qp];
562  Number JxWxRexPhiII = -JxWxRexPhiI * phi[i][qp];
563  for (unsigned int k = 0; k < dim; ++k)
564  Kdiag[k](i,i) += JxWxRexPhiII;
565 
566  // The mass matrix is symmetric, so we calculate
567  // one triangle and add it to both upper and lower
568  // triangles
569  for (unsigned int j = i+1; j != n_u_dofs; ++j)
570  {
571  Number Kij = -JxWxRexPhiI * phi[j][qp];
572 
573  for (unsigned int k = 0; k < dim; ++k)
574  {
575  Kdiag[k](i,j) += Kij;
576  Kdiag[k](j,i) += Kij;
577  }
578  }
579  }
580  }
581  }
582 
583  return request_jacobian;
584 }
585 
586 
587 
589 {
590  const unsigned int dim = this->get_mesh().mesh_dimension();
591 
592  Point p(1./3., 1./3.);
593  Number u = point_value(u_var, p),
594  v = point_value(v_var, p),
595  w = (dim == 3) ? point_value(w_var, p) : 0;
596 
597  libMesh::out << "u(1/3,1/3) = ("
598  << u << ", "
599  << v << ", "
600  << w << ")"
601  << std::endl;
602 }
603 
604 
605 
606 
608 {
609  switch (application)
610  {
611  // lid driven cavity
612  case 0:
613  {
614  // No forcing
615  return Point(0.,0.,0.);
616  }
617 
618  // Homogeneous Dirichlet BCs + sinusoidal forcing
619  case 1:
620  {
621  const unsigned int dim = this->get_mesh().mesh_dimension();
622 
623  // This assumes your domain is defined on [0,1]^dim.
624  Point f;
625 
626  // Counter-Clockwise vortex in x-y plane
627  if (dim==2)
628  {
629  f(0) = std::sin(2.*libMesh::pi*p(1));
630  f(1) = -std::sin(2.*libMesh::pi*p(0));
631  }
632 
633  // Counter-Clockwise vortex in x-z plane
634  else if (dim==3)
635  {
636  f(0) = std::sin(2.*libMesh::pi*p(1));
637  f(1) = 0.;
638  f(2) = -std::sin(2.*libMesh::pi*p(0));
639  }
640 
641  return f;
642  }
643 
644  // 3D test case with quadratic velocity and linear pressure field
645  case 2:
646  {
647  // This problem doesn't make sense in 1D...
648  libmesh_assert_not_equal_to (1, this->get_mesh().mesh_dimension());
649  const Real x=p(0), y=p(1), z=p(2);
650  const Real
651  u=(Reynolds+1)*(y*y + z*z),
652  v=(Reynolds+1)*(x*x + z*z),
653  w=(Reynolds+1)*(x*x + y*y);
654 
655  if (this->get_mesh().mesh_dimension() == 2)
656  return 2*Reynolds*(Reynolds+1)*Point(v*y,
657  u*x);
658  else
659  return 2*Reynolds*(Reynolds+1)*Point(v*y + w*z,
660  u*x + w*z,
661  u*x + v*y);
662  }
663 
664  default:
665  libmesh_error_msg("Invalid application id = " << application);
666  }
667 }
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:196
Real get_elem_solution_derivative() const
The derivative of the current elem_solution w.r.t.
Definition: diff_context.h:432
const DenseMatrix< Number > & get_elem_jacobian() const
Const accessor for element Jacobian.
Definition: diff_context.h:274
Number interior_value(unsigned int var, unsigned int qp) const
Definition: fem_context.C:412
This class provides all data required for a physics package (e.g.
Definition: diff_context.h:55
void get_side_fe(unsigned int var, FEGenericBase< OutputShape > *&fe) const
Accessor for edge/face (2D/3D) finite element object for variable var for the largest dimension in th...
Definition: fem_context.h:317
virtual void zero() override final
Set every element in the vector to 0.
Definition: dense_vector.h:420
ConstFunction that simply returns 0.
Definition: zero_function.h:38
Point forcing(const Point &p)
Definition: naviersystem.C:607
const Elem & get_elem() const
Accessor for current Elem object.
Definition: fem_context.h:908
unsigned int dim
static Point inverse_map(const unsigned int dim, const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true, const bool extra_checks=true)
Definition: fe_map.C:1628
virtual bool side_constraint(bool request_jacobian, DiffContext &context)
Adds the constraint contribution on side of elem to elem_residual.
Definition: naviersystem.C:438
unsigned int n_dof_indices() const
Total number of dof indices on the element.
Definition: diff_context.h:395
This class allows one to associate Dirichlet boundary values with a given set of mesh boundary ids an...
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
The libMesh namespace provides an interface to certain functionality in the library.
const Number zero
.
Definition: libmesh.h:304
Number point_value(unsigned int var, const Point &p) const
Definition: fem_context.C:874
Defines a dense subvector for use in finite element computations.
Definition: assembly.h:38
Gradient interior_gradient(unsigned int var, unsigned int qp) const
Definition: fem_context.C:467
virtual bool contains_point(const Point &p, Real tol=TOLERANCE) const
Definition: elem.C:2754
int8_t boundary_id_type
Definition: id_types.h:51
virtual std::unique_ptr< FunctionBase< Number > > clone() const
Definition: naviersystem.C:68
virtual void init_data()
Initializes the member data fields associated with the system, so that, e.g., assemble() may be used...
Definition: naviersystem.C:77
static Real shape(const unsigned int dim, const FEType &fe_t, const ElemType t, const unsigned int i, const Point &p)
Definition: fe_interface.C:760
Defines a dense submatrix for use in Finite Element-type computations.
Real elem_solution_derivative
The derivative of elem_solution with respect to the current nonlinear solution.
Definition: diff_context.h:496
virtual void init_data() override
Initializes the member data fields associated with the system, so that, e.g., assemble() may be used...
Definition: fem_system.C:873
libmesh_assert(ctx)
const unsigned int _w_var
Definition: naviersystem.C:72
virtual_for_inffe const std::vector< Real > & get_JxW() const
Definition: fe_abstract.h:303
This class provides all data required for a physics package (e.g.
Definition: fem_context.h:62
unsigned int n_points() const
Definition: quadrature.h:131
virtual_for_inffe const std::vector< Point > & get_xyz() const
Definition: fe_abstract.h:280
void get_nothing() const
Definition: fe_abstract.h:269
const boundary_id_type top_id
const DenseVector< Number > & get_elem_residual() const
Const accessor for element residual.
Definition: diff_context.h:242
BdyFunction(unsigned int u_var, unsigned int v_var, unsigned int w_var, Real Reynolds)
Definition: naviersystem.C:47
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual void init_context(DiffContext &context)
Definition: naviersystem.C:178
OStreamProxy out
Function that returns a single value that never changes.
void get_element_fe(unsigned int var, FEGenericBase< OutputShape > *&fe) const
Accessor for interior finite element object for variable var for the largest dimension in the mesh...
Definition: fem_context.h:277
virtual bool mass_residual(bool request_jacobian, DiffContext &context)
Subtracts a mass vector contribution on elem from elem_residual.
Definition: naviersystem.C:498
FEFamily
defines an enum for finite element families.
Base class for functors that can be evaluated at a point and (optionally) time.
void interior_rate(unsigned int var, unsigned int qp, OutputType &u) const
Definition: fem_context.C:1359
const Real _Re
Definition: naviersystem.C:73
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
virtual bool element_constraint(bool request_jacobian, DiffContext &context)
Adds the constraint contribution on elem to elem_residual.
Definition: naviersystem.C:358
This class forms the foundation from which generic finite elements may be derived.
const QBase & get_element_qrule() const
Accessor for element interior quadrature rule for the dimension of the current _elem.
Definition: fem_context.h:802
virtual bool element_time_derivative(bool request_jacobian, DiffContext &context)
Adds the time derivative contribution on elem to elem_residual.
Definition: naviersystem.C:210
virtual void postprocess()
Runs a postprocessing loop over all elements, and if postprocess_sides is true over all sides...
Definition: naviersystem.C:588
const Real pi
.
Definition: libmesh.h:299
const std::vector< std::vector< OutputShape > > & get_phi() const
Definition: fe_base.h:207